紫书 -- 大整数类

Posted jaszzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了紫书 -- 大整数类相关的知识,希望对你有一定的参考价值。

看到紫书上的这一页先是一脸懵逼,不过仔细理解还是觉得挺妙的hhhh

首先贴上前一部分代码:

//结构体BigStruct可用于储存高精度非负整数
struct BigInteger {
    static const int BASE = 100000000;
    static const int WIDTH = 8;
    vector<int> s;

    // 构造函数
    BigInteger(long long num = 0) { *this = num; }
    // this 是一个指向该结构体的指针,所以 *this = num; 就是为了在使用struct声明变量时对变量进行初始化。

    //赋值运算符 ,可用 x = 123456789
    BigInteger operator = (long long num) {
        s.clear();
        do {
            s.push_back(num % BASE);
            num /= BASE;
        } while(num > 0);
        return *this;
    }
    
    //赋值运算符 , 可用 x = "123456789987654321"
    BigInteger operator = (const string &str) {
        s.clear();
        int x, len = (str.length() - 1) / WIDTH + 1;
        for(int i = 0; i < len; ++i) {
            int end = str.length();
            int start = max(0, end-WIDTH);
            sscanf(str.substr(start, end-start).c_str(), "%d", &x);
            s.push_back(x);
        }
        return *this;
    }
};

 通过vector<int> s 来分段保存大数据的值,每满8位数存一次, 两个8位数相加可能等于9位数,而int最多只能保存到2147483647,这样一来使用8位数一存就十分保险。

这样看来,这个栗子还是不难理解的。

不过有一个小点:c_str()函数用法 不过这个例子还是可以望文生义的理解的

 

不过问题的核心在于四则运算的处理

 

    //定义运算符 << >>, 可用cout<< , cin>> 输入输出
    //运算符 <<
    ostream& operator << (ostream &out, const BigInteger& x)
    {
        out << x.s.back();
        for(int i = x.s.size() - 2; i>= 0; i--)
        {
            char buf[20];
            sprintf(buf, "%08d", x.s[i]);
            for(int j = 0; j < strlen(buf); j++) out << buf[j];
        }
        return out;
    }

    //运算符 >>
    istream& operator >> (istream &in, BigInteger& x)
    {
        string s;
        if(! (in >> s)) return in;
        x = s;
        return in;
    }

 

 

    BigInteger operator + (const BigInteger& b) const
    {
        BigInteger c;
        c.s.clear();
        for(int i = 0, g = 0 ; ; i++)
        {
            if(0 == g && i >=s.size() && i >=b.s.size()) break;
            int x = g;
            if(i< s.size()) x += s[i];
            if(i < b.s.size()) x += b.s[i];
            c.s.push_back(x % BASE);
            g = x / BASE;
        }
        return c;
    }

    BigInteger operator += (const BigInteger& b)
    {
        *this = *this + b; return *this;
    }

 

    bool operator < (const BigInteger&  b)const
    {
        if(s.size() != b.s.size()) return s.size() < b.s.size();
        for(int  i = s.size() - 1; i >= 0; i--)
        {
            if(s[i] != b.s[i]) return s[i] < b.s[i];
        }
        return false; //相等    
    }

    bool  operator > (const BigInteger& b) const{return b < *this; }
    bool  operator <= (const BigInteger& b) const{return !(b < *this); }
    bool  operator >= (const BigInteger& b) const{return !( *this < b ); }
    bool  operator != (const BigInteger& b) const{return b < *this || *this < b; }
    bool  operator == (const BigInteger& b) const{return !(b < *this) && !(*this < b); }

 四则运算,经跟踪,发现不同单元中进位联系完全靠变量g,程序在此处处理得十分巧妙。

 

今天先简单看到这,还没有遇到过什么大数处理的题,之后积累更多经验之后再来仔细分析一下吧

以上是关于紫书 -- 大整数类的主要内容,如果未能解决你的问题,请参考以下文章

紫书p155 用中序后序构造二叉树

大整数类 BigInt

大整数类(已完善)

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家