2013-06-19 16 views
0

我是C++新手,嘗試創建「BigInt」類。我決定將大部分實現基於讀取數字讀入向量中。C++將大數字與運算符重載一起添加

到目前爲止,我只寫了輸入字符串的複製構造函數。

Largenum::Largenum(std::string input) 
{ 
for (std::string::const_iterator it = input.begin(); it!=input.end(); ++it) 
    { 
     number.push_back(*it- '0'); 
    } 
} 

我遇到的問題是增加功能。我已經創建了一個函數,在我測試了幾次之後似乎可以工作,但正如您可以看到它非常低效。我有2個不同的載體,例如:

std::vector<int> x = {1,3,4,5,9,1}; 
std::vector<int> y = {2,4,5,6}; 

我想解決這個問題的方法是前短加0,在這種情況下,y矢量,從而使兩個矢量具有相同的大小,例如:

x = {1,3,4,5,9,1}; 
y = {0,0,2,4,5,6}; 

然後使用基本樣式添加它們。

我不想添加向量Y的0面,因爲它會慢很多。我目前的解決方案是反轉矢量,然後push_back適量的0,然後將其逆轉回去。這可能會比較慢,然後簡單地插在前面看起來,我還沒有測試過。

問題是,我做了矢量和push_back結果的所有添加後。我留下了一個向後的向量,我需要再次使用反向!當然,我的方法有更好的方法,但我一直在找到它。理想情況下,我也會讓A const。下面是函數的代碼:

Largenum Largenum::operator+(Largenum &A) 
{ 
    bool carry = 0; 
    Largenum sum;     

    std::vector<int>::size_type max = std::max(A.number.size(), this->number.size()); 
    std::vector<int>::size_type diff = std::abs (A.number.size()-this->number.size()); 

    if (A.number.size()>this->number.size()) 
    { 
     std::reverse(this->number.begin(), this->number.end()); 
     for (std::vector<int>::size_type i = 0; i<(max-diff); ++i) this->number.push_back(0); 
     std::reverse(this->number.begin(), this->number.end()); 
    } 
    else if (this->number.size() > A.number.size()) 
    { 
     std::reverse(A.number.begin(), A.number.end()); 
     for (std::vector<int>::size_type i = 0; i<(max-diff); ++i) A.number.push_back(0); 
     std::reverse(A.number.begin(), A.number.end()); 
    } 
    for (std::vector<int>::size_type i = max; i!=0; --i) 
    { 
     int num = (A.number[i-1] + this->number[i-1] + carry)%10; 
     sum.number.push_back(num); 
     (A.number[i-1] + this->number[i-1] + carry >= 10) ? carry = 1 : carry = 0; 
    } 
    if (carry) sum.number.push_back(1); 

    reverse(sum.number.begin(), sum.number.end()); 

    return sum; 
} 

如果任何人有這將是巨大的任何投入,這是使用C++和它相當壓倒性班我的第一個程序。

+0

如果你想要這樣的前插入,你可能會更好''std :: deque'。我不會對需要這種選擇的算法發表評論。 – chris

+0

是的,我正在研究deque。理想情況下,我會找到一種不需要任何前插入的方法,因爲我懷疑向量會更快。 –

+0

只是一個建議。您可能會對http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/math/BigInteger.java – thefourtheye

回答

1

我認爲你的功能非常接近我見過的最優秀的功能。這裏還有一些建議如何改善它:

  • 十進制數字系統是相當低效率,你有很多大數字的數字。更好地使用更高的基數來減少您必須添加的位數。在人類可讀的表示中讀取和寫入這些數字會有點困難,但您會多次優化操作,因爲您的位數會更少。
  • 當實現大整數我代表他們在相反的順序,因此我有最低有效位在索引0的位置,最重要的一個在數組的末尾。這種方式,當攜帶強迫你添加一個新數字時,你只執行一個push_back,而不是一個完整的反轉。
+0

謝謝,我理解你的第二點,我將改變我的代碼,以另一種方式讀入向量。我不知道你的意思是去更高的基地嗎?你的意思是將數字轉換爲向量中的較高基數,然後在輸出上將它們轉換回來? –

+0

@UserAce是的,你的想法是正確的。例如,如果您使用1000000基數,您的數字將減少6倍的數字,這將導致6倍的總和計算。 –

0

一個問題:現代處理器的整數模量相當慢,甚至與分支預測失誤相比。而不是做一個明確的%10,試試這個爲你的第三個for循環:

int num = A.number[i-1] + this->number[i-1] + carry; 
if(num >= 10) 
{ 
    carry = 1; 
    num -= 10; 
} 
else 
{ 
    carry = 0; 
} 
sum.number.push_back(num);