zoukankan      html  css  js  c++  java
  • 高精度四则运算(整数)

    学习acwing《算法基础课》总结记录

    • 大数超出了语言默认类型能表示的范围,需要特殊处理
    • 将大数存到一个数组里面,先存低位,依次存储高位(四种运算用相同的思路)

    高精度加法

    A + B

    • 人工模拟加法过程
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //C = A + B
    vector<int> add(vector<int> &A, vector<int> &B) {
        vector<int>  C;
        
        int t = 0; //进位
        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;
        }
        //最高位如果有进位,则补1
        if(t) C.push_back(1);
        
        return C;
    }
    
    int main() {
        string a, b;
        vector<int> A, B;
        
        cin >> a>> b;
        //用数组表示整数,逆序存储,防止产生进位时数组搬移
        for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
        for(int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
        
        auto C = add(A, B);
        
        //注意顺序
        for(int i = C.size() - 1; i >= 0; i-- ) {
            printf("%d", C[i]);
        }
        
        return 0;
    }
    

    高精度减法

    A - B

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //比较A与B的大小
    bool comp(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;
    }
    
    vector<int> sub(vector<int> &A, vector<int> &B){
        vector<int> C;
        for(int i =0, t = 0; i < A.size(); i++){
            t = A[i] - t; //减去上一位的借位
            if(i < B.size()) t -= B[i];
            //如果是负数,自动借位,如果是正数,取余后加的10抵消
            C.push_back((t + 10) % 10);//处理技巧
            if(t < 0) t = 1;
            else t = 0;
        }
        while(C.size() > 1 && C.back() == 0) C.pop_back(); //去掉前导零
    	
        return C;
    }
    
    int main() {
        string a, b;
        cin >> a >> b;
        vector<int> A, B, C;
        
        for(int i = a.size() - 1; i >= 0; i -- ) A.push_back(a[i] - '0');
        for(int i = b.size() - 1; i >= 0; i -- ) B.push_back(b[i] - '0');
        
        //始终用大数减小数
        if(comp(A,B)) C = sub(A, B);
        else{
            cout<<"-";
            C = sub(B, A);
        }
        for(int i = C.size() - 1; i >= 0; i -- ) cout<<C[i];
        
        return 0;
    }
    

    高精度乘法

    A * b
    一个大数乘以一个小数
    将b作为一个整体,依次用A的每一位去乘,处理进位

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //处理技巧类似大整数加法
    //将b看作一个整体,依次用A的每一位去乘以b
    vector<int> mult(vector<int> &A, int b) {
        vector<int> c;
        int t = 0;
        for(int i = 0; i < A.size() || t; i ++ ){
            if(i < A.size()) t += A[i] * b;
            c.push_back(t % 10);
            t /= 10; //和加法类似但是有区别,这儿的结果有很多种情况
        }
        //b可能为0 //所以这儿需要去掉前导零
        while (c.size() > 1 && c.back() == 0) c.pop_back();
        
        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');
        
        auto c = mult(A, b);
        
        for(int i = c.size() - 1; i >= 0; i -- ) printf("%d", c[i]);
        
        return 0;
    }
    

    高精度除法

    A / b

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    vector<int> div(vector<int> &A, int b, int &r) {
        vector<int> c;
        for(int i = A.size() - 1; i >= 0; i -- ){
            r = r * 10 + A[i];
            c.push_back(r / b);
            r %= b;
        }
        //计算出的结果和定义的大整数的存储方向是反的,为了保证返回值可以参与其他运算,返回前反转
        reverse(c.begin(), c.end());
        while(c.size() > 1 && c.back() == 0 ) c.pop_back();
        
        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');
        
        int r = 0;//余数
        auto c = div(A, b, r);
        
        for(int i = c.size() - 1; i >= 0; i -- ) 
            printf("%d", c[i]);
        cout << endl << r << endl;
        
        return 0;
    }
    
  • 相关阅读:
    VIJOS P1057盖房子 (动态规划)
    RQNOJ PID57 / 找啊找啊找GF
    RQNOJ PID302 / [NOIP2001]统计单词个数 (动态规划)
    hdu 3829 Cat VS Dog 最大独立集
    并查集 找k颗树使节点数最多
    在 Sublime Text 3 中配置编译和运行 Java 程序
    在 Sublime Text 3 中配置编译和运行 Java 程序
    StarUML license key
    StarUML license key
    测试对于list的sort与sorted的效率
  • 原文地址:https://www.cnblogs.com/huhu555/p/14649695.html
Copyright © 2011-2022 走看看