• 高精度模板(Vector实现更加方便)


    计算的数long long 甚至更大的数据类型的都存不下的时候,应该怎么办 ?

    解决方法 :我们可以把一个很大的数当做字符串进行处理,这时候就需要用到高精度。
    

    话不多说,咱们边看代码边处理 :

    加法 :

    PK一下

    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main(void) {
    	vector<int> add(vector<int> &A,vector<int> &B);   
            // Vector容器相当于是一个数组,比数组处理起来更加方便 (返回一个 vector 类型的值)
    	vector<int>A,B,C;
    	string a,b;
    	cin >> a >> b;                                    // 输入两个大数
    	for(int i = a.length() - 1; ~i; i --) A.push_back(a[i] - '0');  
             // 我们进行加法的时候要从低位开始,字符串输入的时候低位在最后,所以我们要将字符串逆序存储在容器中
    	for(int i = b.length() - 1; ~i; i --) B.push_back(b[i] - '0');
    	C = add(A,B);
    	for(int i = C.size() - 1; ~i; i --) cout << C[i];                
            // 同理,输出的时候也要逆序输出
    	return 0;
    }
    
    vector<int> add(vector<int> &A,vector<int> &B) {
    	if(A.size() < B.size()) return add(B,A);         // 尽量用长的 + 短的,因为这样多余的部分我们就可以直接进行处理了
    	vector<int> C;                                   // 设置一个 vector 类型的变量,用来作为返回的值
    	int t = 0;
    	for(int i = 0; i < A.size(); i ++) {
    		t += A[i];
    		if(B.size() > i) t += B[i];              // B 有一定的限制,不能一直加 呀 
    		C.push_back(t % 10);
    		t /= 10;                                 // 进位 
    	}
    	if(t) C.push_back(t);                            // 可能会多出来一个,例如3位数 + 3 位数 ,结果有可能是 4 位数
    	return C;
    
    }
    
    

    减法 :

      注意 : 1、答案有可能是负数
             2、最后存储在 vector 中的字符串可能会存在前导 0 
    

    PK一下

    Code :

    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main(void) {
    	void ClearZero(vector<int> &A);                          // Clear 前导 0
    	bool cmp(vector<int> &A,vector<int> &B);                 // 比较两个字符串,让 大的减去 小的
    	vector<int> sub(vector<int> &A,vector<int> &B);
    	
    	vector<int>A,B,C;
    	string a,b;
    	cin >> a >> b;
    	for(int i = a.length() - 1; ~i; i --) A.push_back(a[i] - '0');
    	for(int i = b.length() - 1; ~i; i --) B.push_back(b[i] - '0');
    	ClearZero(A),ClearZero(B);                              // 先去除字符串计算本身的的前导 0
    	if(cmp(A,B)) {
    		C = sub(A,B);
    	} else {
    		C = sub(B,A);                                  // 交换
    		cout << "-";                                   // 输出 - 代表负数
    	}
    	for(int i = C.size() - 1; ~i; i --) cout << C[i];
    	cout << endl << r << endl; 
    	return 0;
    }
    
    void ClearZero(vector<int> &A) {
    	while(A.size() > 1 && A.back() == 0) A.pop_back();
    	return ;
    }
    
    bool cmp(vector<int> &A,vector<int> &B) {
    	if(A.size() != B.size()) return A.size() >= B.size();
    	for(int i = A.size(); ~i; 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;
       int t = 0;
       for(int i = 0; i < A.size(); i ++) {
       		t = A[i] - t;
       		if(B.size() > i) t -= B[i];
       		C.push_back((t + 10) % 10);
       		if(t < 0) t = 1;                             // 如果得到的是负数,说明需要借位,这时候下次计算时就需要 - 1
       		else t = 0;
       } 
      while(C.size() > 1 && C.back() == 0) C.pop_back();         // Clear 前导 0
       return C;
    }
    
    

    乘法(高精度 * 整数) :

    PK一下

    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main(void) {
    
    	vector<int> mul(vector<int> &A,int b);
    	
    	vector<int>A,B,C;
    	string a;
    	int value;
    	cin >> a >> value;
    	for(int i = a.length() - 1; ~i; i --) A.push_back(a[i] - '0');
    	C = mul(A,value);
    	for(int i = C.size() - 1; ~i; i --) cout << C[i];
    	return 0;
    }
    
    vector<int> mul(vector<int> &A,int b) {
    	int t = 0;
    	vector<int> C;
    	for(int i = 0; i < A.size(); i ++) {   // 模拟乘法过程
    		t += A[i] * b;
    		C.push_back(t % 10);
    		t /= 10;
    	}
    	while(t) {                             // 处理最后的那个数
    		C.push_back(t % 10);
    		t /= 10;
    	}
    	return C;
    }
    

    除法:

    PK一下

    #include <vector>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main(void) {
    	vector<int> div(vector<int> &A,int b,int &r);
    	
    	vector<int>A,B,C;
    	string a;
    	int value;
    	cin >> a >> value;
    	for(int i = a.length() - 1; ~i; i --) A.push_back(a[i] - '0');
    	int r;  // 余数
    	C = div(A,value,r);
    	for(int i = C.size() - 1; ~i; i --) cout << C[i];
    	cout << endl << r << endl;
    	return 0;
    }
    
    
    vector<int> div(vector<int> &A,int b,int &r) {   // 引用变量,相当于是全局变量,直接在函数内部进行修改
    	vector<int> C;
    	r = 0;                                   // 初始化
    	for(int i = A.size() - 1; ~i; i --) {    // 除法是从高位向低位进行的
    		r = r * 10 + A[i];               // 得到除数,每次向后移动一位(余数要乘 10 -- 可以模拟一下,很好理解)
    		C.push_back(r / b);              // 刚开始可能为 0
    		r %= b;
    	}
    	reverse(C.begin(),C.end());              // 反转是为了处理前导 0 
    	while(C.size() > 1 && C.back() == 0) C.pop_back();
    	return C;
    }
    
    如果说年轻人未来是一场盛宴的话,那么我首先要有赴宴的资格。
  • 相关阅读:
    高精度入门(减法、加法、乘法)之 CODE[VS] 3115、3116、3117
    DP经典 之 CODE[VS] 1576 最长严格上升子序列 (O(n^2) 和 O(nlogn))
    CODE[VS] 1098 均分纸牌 ( 2002年NOIP全国联赛提高组)
    C++ string 与 int 等类型 的相互转换
    组合数学 + 大数乘法 + 大数除法 之 hdu 1261 字串数
    自然语言理解 之 统计词频
    Leetcode_10【正则表达式匹配】
    01——字符串反转
    Leetcode_09【回文数】
    Leetcode_07【整数反转】
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12246515.html
Copyright © 2020-2023  润新知