總結:大整數類加法、乘法

總結了一下大整數的加、乘操作涉及的代碼。
需要注意的點:

  • 注意C++類的語法,尤其是構造函數、重載內訪問另一個對象
  • 數字在數組中是逆序存放的,每一位都是十進制表示,用len來記錄這個大整數的有效長度
  • 加法操作時,由於兩個數的長度可能不一,因此不能漏掉多出來的那一段,以及最後的溢出位。
  • 乘法操作時,每一次外層循環(從最低位開始遍歷第二個數)得到的乘法結果,要和前一次乘法結果錯開一位相加。
  • 輸出時,注意len=0即數字爲0的情況。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;

class BigInt //自定義大整數類
{
public:
    int num[105], len; //數字逆序存放

    BigInt():len(0){} //初始化

    BigInt(long long int n):len(0) //構造函數:long long int
    {
        while(n > 0)
        {
            num[len++] = n % 10;
            n /= 10;
        }
    }

    BigInt(string s):len(0) //構造函數:字符串
    {
        for (int i = s.length()-1; i >= 0; --i)
            num[len++] = s[i]-'0';
    }

    BigInt operator + (const BigInt & b) //重載+
    {
        BigInt res;
        int cnt, carry = 0; //carry存放將要加到這一位結果的值
        for (cnt = 0; cnt < this->len || cnt < b.len || carry > 0; ++cnt) //不要漏掉最後carry>0的情況
        {
            if (cnt < this->len)
                carry += this->num[cnt];
            if (cnt < b.len)
                carry += b.num[cnt];
            res.num[cnt] = carry % 10;
            carry /= 10;
        }
        res.len = cnt;
        return res;
    }

    BigInt operator += (const BigInt & b) //重載+=
    {
        *this = *this + b;
        return *this;
    }

    BigInt operator * (const BigInt & b) //重載*
    {
        BigInt res;
        int mul[105] = {0}; //存放臨時結果
        for (int i = 0; i < b.len; ++i) //模擬乘法運算和錯位相加,先不考慮進位
        {
            for (int j = 0; j < len; ++j)
                mul[i+j] += b.num[i] * num[j];
        }
        int last = 100;
        while (last >= 0 && mul[last] == 0) last--; //確定非0的最高位下標last
        if (last >= 0)
        {
            int carry = 0;
            for (int i = 0; i <= last; ++i)  //統一進位
            {
                mul[i] += carry;
                carry = mul[i] / 10;
                mul[i] %= 10;
            }
            if (carry) //最高位溢出
                mul[last+1] = carry;
            res.len = (carry == 0) ? last+1 : last+2; //結果的長度
            memcpy(res.num, mul, sizeof(int)*105); //數值拷貝到結果中
        }
        return res;
    }

    BigInt operator *= (const BigInt &b) //重載*=
    {
        *this = *this * b;
        return *this;
    }

    void print() //輸出
    {
        printf("Length: %d\nValue: ", len);
        if (len == 0) //注意值爲0時長度爲0
        {
            printf("0\n");
            return;
        }
        for (int i = len-1; i >= 0; --i)
            printf("%d", num[i]);
        printf("\n");
    }

};

const int maxn = 10005;
BigInt a[maxn];

void addTest() //POJ 1503---AC
{
    int i = 0;
    string s;
    BigInt ans(0);
    while (cin >> s && s != "0")
    {
        a[i] = BigInt(s);
        ans += a[i];
        i++;
    }
    ans.print();
}

void mulTest() //測試:大數乘法
{
    string a,b;
    BigInt x, y, z;
    while(cin >> a >> b)
    {
        x = BigInt(a);
        y = BigInt(b);
        z = x * y;
        z.print();
    }
}

void FibonacciAdd() //測試:計算斐波那契數列
{
    a[0] = BigInt(0);
    a[1] = BigInt(1);
    int n;
    while(cin >> n)
    {
        for (int i = 2; i <= n; ++i)
        {
            if (a[i].len == 0)
                a[i] = a[i-1] + a[i-2];
        }
        a[n].print();
    }
}

int main()
{
    //addTest();
    //FibonacciAdd();
    mulTest();
    return 0;
}
發佈了116 篇原創文章 · 獲贊 27 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章