高精度
主要是用来对超出int范围外的数字进行算数运算的一种算法
高精度 & 4
高精度加法
假如现在给两个高精度的数字A,B
首先我们需要将A的每一位存储到数组或者是集合当中,B也是同样的道理(当然这里需要反向存储,因为我们需要先去计算个位,然后判断下一位是否需要进位)
在进行加法运算的时候我们需要考虑这一位上是否有数,我们只需要加上A,B上这一位有数的值即可
第i位保留的结果为和取模操作,除以10判断下一位是否需要进位
循环结束我们需要判断t是否还有值,如果有值只需要再添加一个1代表进位操作。ex:90 + 10 当i = 2的是否t 等于1,我们需要在00的前面加上一即可
#include <bits/stdc++.h> using namespace std; vector<int> add(vector<int> &A,vector<int> &B) { vector<int> C; int i = 0,t = 0; while(i < A.size() || i < B.size()) { if(i < A.size()) t += A[i]; if(i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; i++; } 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'); for(int i = b.size() - 1;i >= 0;i--) B.push_back(b[i] - '0'); auto res = add(A,B); for(int i = res.size() - 1;i >= 0;i--) cout << res[i]; cout << endl; return 0; }
|
高精度减法
和高精度加法一样,我们反向存储字符串
如果发现对位差值为负数的话,那么下一位需要先减1,再进行A[i] - B[i]
的操作
最后别忘了,需要去前导0,当然如果A - B结果就是0的话,那么没有必要去0了
#include <bits/stdc++.h> using namespace std; bool cmp(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; 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; 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; 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(cmp(A,B)) { auto ans = sub(A,B); for(int i = ans.size() - 1;i >= 0;i--) cout << ans[i]; }else { auto ans = sub(B,A); cout << "-"; for(int i = ans.size() - 1;i >= 0;i--) cout << ans[i]; } cout << endl; return 0; }
|
高精度乘法
以下代码主要适用于A为高精度数字,B为int范围内的数字
如果两个都是高精度数字,A的长度为N,B的长度为M,时间复杂度为O(N * M)很容易超时
所以很少出现两个数都是高精度的情况
#include <bits/stdc++.h> using namespace std;
vector<int> mul(vector<int> &A,int b) { vector<int> v; int t = 0; for(int i = 0; i< A.size();i++) { if(i < A.size()) t += A[i] * b; v.push_back(t % 10);
t /= 10; }
if(t) v.push_back(t);
while(v.size() > 1 && v.back() == 0) v.pop_back();
return v; }
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 = mul(A,b);
for(int i = c.size() - 1;i >= 0;i--) cout << c[i]; return 0; }
|
高精度除法
思路
举个例子:200 / 3 -> (2 / 3 == 0) -> (2 * 10 / 3 == 6) -> (2 * 10 / 3 == 6) ———> 066 -> 66
我们是从分母进行出发,每一次向C中添加的位为每一位/ 3的值,下一位的初始值设置为上一次保存下来的值 * 10 + 本次的值接着进行同样的取模和除法运算
#include <bits/stdc++.h> using namespace std;
vector<int> mul(vector<int> &A,int b,int &t) { vector<int> C; t = 0; for(int i = A.size() - 1;i >= 0;i--) { t = t * 10 + A[i]; C.push_back(t / b); t %= 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; auto c = mul(A,b,r); for(int i = c.size() - 1;i >= 0;i--) cout << c[i]; cout << endl; cout << r << endl; return 0; }
|