zoukankan      html  css  js  c++  java
  • 高精度与大整数

    高精度与大整数

    1. 高精度

    1.1 加法(大数+大数)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    // 返回C = A + B
    vector<int> add(vector<int> &A, vector<int> &B)  // A和B存储的都是逆序
    {
        int t = 0;  // 记录进位情况
        vector<int> C;  // 记录答案
        for (int i = 0; i < A.size() || i < B.size(); ++i)
        {
            if (i < A.size() ) t += A[i];  // 如果这一位有数字
            if (i < B.size())  t += B[i];
            C.push_back(t % 10);  // 加到这一位上
            t /= 10;  // 换成下一位的数字
        }
        if (t) C.push_back(1);  // 如果有剩余,在最高位补上一
        return C;
    }
    
    int main()
    {
        string a, b;
        cin >> a >> b;
        vector<int> A, B;
        for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 如果a是123,那么放入vector的顺序为321
        for (int j = b.size() - 1; j >= 0; --j) B.push_back(b[j] - '0');
        auto C = add(A, B);
        for (int i = C.size() - 1; i >= 0; --i) cout << C[i];  // 如果答案是123,那么答案的vector C内为321
        return 0;
    }
    

    1.2 减法(大数-大数)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    // A >= B:true, A<B:false
    bool compare(vector<int> &A, vector<int> &B)
    {
        if (A.size() != B.size()) return A.size() > B.size();
        for (int i = A.size() - 1; i >= 0; --i)
            if (A[i] != B[i]) return A[i] > B[i];
        return true;
    }
    
    // C = A - B
    vector <int> sub(vector<int> &A, vector<int> &B)
    {
        vector <int> C;  // 用来存储答案
        int t = 0;  // 记录是否去高位借位
        for (int i = 0; i < A.size(); ++i)
        {
            t = A[i] - t;
            if (i < B.size() ) t -= B[i];  
            C.push_back((t + 10) % 10);
            if (t < 0) t = 1; // 复原t
            else t = 0;
        }
        while (C.size() > 1 && C.back() == 0) C.pop_back();  // 去除高位的前导0
        return C;
    }
    
    int main()
    {
        string a, b;
        cin >> a >> b;
        vector <int> A, B;
        for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 如果a是123,那么放入vector的顺序为321
        for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - '0');
        vector<int> C;
        if (!compare(A, B))
        {
            printf("-");
            C = sub(B, A);
        }
        else C = sub (A, B);
        for (int i = C.size() - 1; i >= 0; --i)  // 如果答案是123,那么答案的vector C内为321
        return 0;
            cout << C[i];
        return 0;
    }
    

    1.3 乘法(大数*小数)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    // C = A * n
    vector<int> mul(vector<int> &A, int n)
    {
        vector<int> C;  // 存储答案
        int t = 0;
        for (int i = 0; i < A.size() || t; ++i)
        {
            if (i < A.size()) t += A[i] * n;
            C.push_back(t % 10);  // 放入当前位的数字
            t /= 10;
        }
        return C;
    }
    
    int main()
    {
        string a;
        int b;
        cin >> a >> b;
        vector<int> A;
        for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 如果a是123,那么放入vector的顺序为321
        auto C = mul(A, b);
        for (int i = C.size() - 1; i >= 0; --i)  // 如果答案是123,那么答案的vector C内为321
            cout << C[i];
        return 0;
    }
    

    1.4 除法(大数/小数)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    vector<int > div(vector<int> &A, int b, int &r)
    {
        r = 0;  // 余数
        vector<int> C;  // 存储答案
        for (int i = A.size() - 1; i >= 0; --i)
        {
            r = r * 10 + A[i];  
            C.push_back(r / b);  // 放入除完的结果到答案中
            r = r % b;
        }
        reverse(C.begin(), C.end());  // C一开始存储的时候是正序,改成反序
        while (C.size() > 1 && C.back() == 0) C.pop_back();  // 去掉前导0
        return C;
    }
    
    int main()
    {
        string a;
        int b, r;
        cin >> a >> b;
        vector<int> A;
        for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');  // 如果a是123,那么放入vector的顺序为321
        auto C = div(A, b, r);
        for (int i = C.size() - 1; i >= 0; --i)  // 商
            cout << C[i] ;
        cout << endl << r << endl;  // 余数
        return 0;
    }
    

    2. 大整数

    #include <bits/stdc++.h>
    using namespace std;
    //大数
    struct BigInteger
    {
        static const int BASE = 100000000; //和WIDTH保持一致
        static const int WIDTH = 8;        //八位一存储,如修改记得修改输出中的%08d
        bool sign;                         //符号, 0表示负数
        size_t length;                     //位数
        vector<int> num;                   //反序存
                                           //构造函数
        BigInteger(long long x = 0) { *this = x; }
        BigInteger(const string &x) { *this = x; }
        BigInteger(const BigInteger &x) { *this = x; }
        //剪掉前导0,并且求一下数的位数
        void cutLeadingZero()
        {
            while (num.back() == 0 && num.size() != 1)
            {
                num.pop_back();
            }
            int tmp = num.back();  // tmp是最高位
            if (tmp == 0)  // 最高位为0,长度为1
            {
                length = 1;
            }  // 最高位不为0
            else
            {
                length = (num.size() - 1) * WIDTH;
                while (tmp > 0)
                {
                    length++;
                    tmp /= 10;
                }
            }
        }
        //赋值运算符
        BigInteger &operator=(long long x)
        {
            num.clear();
            if (x >= 0)
            {
                sign = true;
            }
            else
            {
                sign = false;
                x = -x;
            }
            do
            {
                num.push_back(x % BASE);
                x /= BASE;
            } while (x > 0);
            cutLeadingZero();
            return *this;
        }
        BigInteger &operator=(const string &str)
        {
            num.clear();
            sign = (str[0] != '-'); //设置符号
            int x, len = (str.size() - 1 - (!sign)) / WIDTH + 1;
            for (int i = 0; i < len; i++)
            {
                int End = str.size() - i * WIDTH;
                int start = max((int)(!sign), End - WIDTH); //防止越界
                sscanf(str.substr(start, End - start).c_str(), "%d", &x);
                num.push_back(x);
            }
            cutLeadingZero();
            return *this;
        }
        BigInteger &operator=(const BigInteger &tmp)
        {
            num = tmp.num;
            sign = tmp.sign;
            length = tmp.length;
            return *this;
        }
        //绝对值
        BigInteger abs() const
        {
            BigInteger ans(*this);
            ans.sign = true;
            return ans;
        }
        //正号
        const BigInteger &operator+() const { return *this; }
        //负号
        BigInteger operator-() const
        {
            BigInteger ans(*this);
            if (ans != 0)
                ans.sign = !ans.sign;
            return ans;
        }
        // + 运算符
        BigInteger operator+(const BigInteger &b) const
        {
            if (!b.sign)
            {
                return *this - (-b);
            }
            if (!sign)
            {
                return b - (-*this);
            }
            BigInteger ans;
            ans.num.clear();
            for (int i = 0, g = 0;; i++)
            {
                if (g == 0 && i >= num.size() && i >= b.num.size())
                    break;
                int x = g;
                if (i < num.size())
                    x += num[i];
                if (i < b.num.size())
                    x += b.num[i];
                ans.num.push_back(x % BASE);
                g = x / BASE;
            }
            ans.cutLeadingZero();
            return ans;
        }
        // - 运算符
        BigInteger operator-(const BigInteger &b) const
        {
            if (!b.sign)
            {
                return *this + (-b);
            }
            if (!sign)
            {
                return -((-*this) + b);
            }
            if (*this < b)
            {
                return -(b - *this);
            }
            BigInteger ans;
            ans.num.clear();
            for (int i = 0, g = 0;; i++)
            {
                if (g == 0 && i >= num.size() && i >= b.num.size())
                    break;
                int x = g;
                g = 0;
                if (i < num.size())
                    x += num[i];
                if (i < b.num.size())
                    x -= b.num[i];
                if (x < 0)
                {
                    x += BASE;
                    g = -1;
                }
                ans.num.push_back(x);
            }
            ans.cutLeadingZero();
            return ans;
        }
        // * 运算符
        BigInteger operator*(const BigInteger &b) const
        {
            int lena = num.size(), lenb = b.num.size();
            BigInteger ans;
            for (int i = 0; i < lena + lenb; i++)
                ans.num.push_back(0);
            for (int i = 0, g = 0; i < lena; i++)
            {
                g = 0;
                for (int j = 0; j < lenb; j++)
                {
                    long long x = ans.num[i + j];
                    x += (long long)num[i] * (long long)b.num[j];
                    ans.num[i + j] = x % BASE;
                    g = x / BASE;
                    ans.num[i + j + 1] += g;
                }
            }
            ans.cutLeadingZero();
            ans.sign = (ans.length == 1 && ans.num[0] == 0) || (sign == b.sign);
            return ans;
        }
        //*10^n 大数除大数中用到
        BigInteger e(size_t n) const
        {
            int tmp = n % WIDTH;
            BigInteger ans;
            ans.length = n + 1;
            n /= WIDTH;
            while (ans.num.size() <= n)
                ans.num.push_back(0);
            ans.num[n] = 1;
            while (tmp--)
                ans.num[n] *= 10;
            return ans * (*this);
        }
        // /运算符 (大数除大数)
        BigInteger operator/(const BigInteger &b) const
        {
            BigInteger aa((*this).abs());
            BigInteger bb(b.abs());
            if (aa < bb)
                return 0;
            char *str = new char[aa.length + 1];
            memset(str, 0, sizeof(char) * (aa.length + 1));
            BigInteger tmp;
            int lena = aa.length, lenb = bb.length;
            for (int i = 0; i <= lena - lenb; i++)
            {
                tmp = bb.e(lena - lenb - i);
                while (aa >= tmp)
                {
                    str[i]++;
                    aa = aa - tmp;
                }
                str[i] += '0';
            }
            BigInteger ans(str);
            delete[] str;
            ans.sign = (ans == 0 || sign == b.sign);
            return ans;
        }
        // %运算符
        BigInteger operator%(const BigInteger &b) const
        {
            return *this - *this / b * b;
        }
        // ++ 运算符
        BigInteger &operator++()
        {
            *this = *this + 1;
            return *this;
        }
        // -- 运算符
        BigInteger &operator--()
        {
            *this = *this - 1;
            return *this;
        }
        // += 运算符
        BigInteger &operator+=(const BigInteger &b)
        {
            *this = *this + b;
            return *this;
        }
        // -= 运算符
        BigInteger &operator-=(const BigInteger &b)
        {
            *this = *this - b;
            return *this;
        }
        // *=运算符
        BigInteger &operator*=(const BigInteger &b)
        {
            *this = *this * b;
            return *this;
        }
        // /= 运算符
        BigInteger &operator/=(const BigInteger &b)
        {
            *this = *this / b;
            return *this;
        }
        // %=运算符
        BigInteger &operator%=(const BigInteger &b)
        {
            *this = *this % b;
            return *this;
        }
        // < 运算符
        bool operator<(const BigInteger &b) const
        {
            if (sign != b.sign) //正负,负正
            {
                return !sign;
            }
            else if (!sign && !b.sign) //负负
            {
                return -b < -*this;
            }
            //正正
            if (num.size() != b.num.size())
                return num.size() < b.num.size();
            for (int i = num.size() - 1; i >= 0; i--)
                if (num[i] != b.num[i])
                    return num[i] < b.num[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); } //==运算符
        // 逻辑运算符
        bool operator||(const BigInteger &b) const { return *this != 0 || b != 0; } // || 运算符
        bool operator&&(const BigInteger &b) const { return *this != 0 && b != 0; } // && 运算符
        bool operator!() { return (bool)(*this == 0); }                             // ! 运算符
        //重载<<使得可以直接输出大数
        friend ostream &operator<<(ostream &out, const BigInteger &x)
        {
            if (!x.sign)
                out << '-';
            out << x.num.back();
            for (int i = x.num.size() - 2; i >= 0; i--)
            {
                char buf[10];
                //如WIDTH和BASR有变化,此处要修改为%0(WIDTH)d
                sprintf(buf, "%08d", x.num[i]);
                for (int j = 0; j < strlen(buf); j++)
                    out << buf[j];
            }
            return out;
        }
        //重载>>使得可以直接输入大数
        friend istream &operator>>(istream &in, BigInteger &x)
        {
            string str;
            in >> str;
            size_t len = str.size();
            int start = 0;
            if (str[0] == '-')
                start = 1;
            if (str[start] == '')
                return in;
            for (int i = start; i < len; i++)
            {
                if (str[i] < '0' || str[i] > '9')
                    return in;
            }
            x.sign = !start;
            x = str.c_str();
            return in;
        }
    };
    
    struct Tag
    {
        string name;
        BigInteger num;
    }tag[1100];
    // 可用于sort函数
    bool cmp(struct Tag a, struct Tag b)
    {
        return a.num > b.num;
    }
    
    int main()
    {
        BigInteger n;
        cin >> n;
        cout << n.e(3) << endl;  // 返回n*(10^3)
        cout << n.abs() << endl;
        string a, b;
        cin >> a >> b;
        BigInteger c(a), d(b);
        cout << c + d << endl;
        if (c == 0) cout << "yes
    ";
        return 0;
    }
    
  • 相关阅读:
    用迁移学习创造的通用语言模型ULMFiT,达到了文本分类的最佳水平
    论文分享|《Universal Language Model Fine-tuning for Text Classificatio》
    tesnorflow实现N个epoch训练数据读取的办法
    理解TensorFlow的Queue
    tensorflow基本操作介绍
    前端框架 Vue 初探
    LeetCode 292 Nim Game(Nim游戏)
    设计模式有感
    说说翻转的数据结构课
    java 中xml转换为json对象
  • 原文地址:https://www.cnblogs.com/spciay/p/13064073.html
Copyright © 2011-2022 走看看