AcWing 算法基础课笔记【基础算法篇】3. 高精度运算
大整数存储
思路
存储时要倒着存,方便进位,如 A [ 0 ] A[0] A[0]对应个位, A [ 1 ] A[1] A[1]对应十位,以此类推
模板
string a, b;
vector<int> A, B; // #include <vector>
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--) cout << C[i];
高精度加法
思路
第一步,存储大整数
第二步,用t当作上一位的进位,初始设为0,C为答案数组
- 令 t = A i + B i + t t=A_{i}+B_{i}+t t=Ai+Bi+t
- t t t的个位为 C i C_{i} Ci的值,十位表示是否有进位
- t t t变为自身的十位(0或1)
- 当最高位仍有进位时,将则在数组 C C C最后面加上一位1
第三步,从末尾开始倒序输出C数组
模板
vector<int> add(vector<int> &A, vector<int> &B){ // 使用&A就不需要复制整个数组
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;
}
if(t) C.push_back(1);
return C;
}
高精度减法
思路
第一步 存储大整数,判断A与B的大小
// 判断A是否>=B
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;
}
int main(){
···
if(cmp(A, B)){
auto C = sub(A, B);
for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
else{
auto C = sub(B, A);
cout << '-';
for(int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
···
}
第二步,用C作为答案数组,t作为借位,开始相减
- 若
A
i
−
B
i
−
t
<
0
A_{i}-B_{i}-t<0
Ai−Bi−t<0,则将该式
+
10
+10
+10赋给
C
i
C_{i}
Ci,且
t
=
1
t=1
t=1;
若大于0,则直接将该式赋给 C i C_{i} Ci,且 t = 0 t=0 t=0 - 最后删除数组 C C C中存在的多余的0
模板
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];
C.push_back((t + 10) % 10); // 若t小于0,则该式表示t+10;若t大于0,则该式表示t
if(t < 0) t = 1;
else t = 0;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
高精度乘法(低精乘高精)
思路
用t当作上一位的进位,初始 t = 0 t=0 t=0,C为答案数组
- 令 t = A i ∗ b + t t=A_{i}*b+t t=Ai∗b+t
- t t t的个位为 C i C_{i} Ci
- t t t的进位为 t / 10 t/10 t/10
- 若最后还有进位,则一位一位加上
- 最后删除数组 C C C中存在的多余的0
模板
vector<int> mul(vector<int> &A, int b){
vector<int> C;
for(int i = 0, t = 0; i < A.size() || t; i++){
if(i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
高精度除法(高精除以低精)
思路
用r作为上一位的余数,从最高位开始除
- 令 r = r ∗ 10 + A i r=r*10+A_{i} r=r∗10+Ai,则商 C i C_{i} Ci为 r / b r/b r/b,余数r为 r / b r/b r/b的余数
- 反转数组C
- 除去前端的0
模板
vector<int> div(vector<int> &A, int b, int &r){
vector<int> C;
r = 0;
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(); // C数组的尾部的0即为输出数据前端的0
return C;
}

223

被折叠的 条评论
为什么被折叠?



