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;
    }
    
  • 相关阅读:
    LSMW TIPS
    Schedule agreement and Delfor
    Running VL10 in the background 13 Oct
    analyse idoc by creation date
    New Journey Prepare
    EDI error
    CBSN NEWS
    Listen and Write 18th Feb 2019
    Microsoft iSCSI Software Target 快照管理
    通过 Microsoft iSCSI Software Target 提供存储服务
  • 原文地址:https://www.cnblogs.com/huhu555/p/14649695.html
Copyright © 2011-2022 走看看