1 序言(some废话&鸡汤)
高精度通常在面试很少会考到,笔试会涉及,但自己想加强自己的逻辑能力,因此看了高精度的加减,乘除就劝退.
鸡汤:学代码,一定不能止步于算法思路,要落实到代码实现上。
2 理论部分
既然目的是训练逻辑能力,普通的加减有哪些步骤?每一步如何用计算机语言去实现呢?至于高精度就再考虑个范围问题即可。
落实细节
1.A+B 高精度
- 大整数怎么存?
int 肯定不行。存储的方式是用数组来存储,且采用倒序存储。可借鉴大端小端法(这里借用某位博主的图方便理解)
因为高精度位数很多,因此输入时以字符串形式输入,再用数组的形式存储即可。 - 如何加呢?
我们计算加法的时候,采取对齐方式,逐个进位。
进位的时候,需保留个位,用取模运算%。
- A-B
- 减法逻辑
A-B-t(t是借位)一般情况:
1.>=0够减,直接算A-B-t.
2.<0 不够减,需借位,A-B+10-t. - t借位逻辑
1.t>=0 => t
2. t<0 => t+10 - 高精度减法模板仅适用A>=B,当且仅当A<B时 => -(B-A).
3 代码模板
- 高精度加法模板
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;
//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;
}
if (t) C.push_back(1);
return C;
}
int main() {
string a, b;
vector<int> A, B; //vector是c++的一种容器,可以随时调整数组长度 动态数组
cin >> a >> b; //a='12345'
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // 因为是字符串,要变成数字整型,后面得-‘0’.
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
vector<int> C = add(A, B);
// auto指编译器自动推断什么类型 这里等价于vector<int>
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
return 0;
}
- 高精度减法模板
t=1 表示借位, t=0表示无借位
#include<iostream>
#include<vector>
using namespace std;
const int N = 1e6 + 10;
//判断是否A>=B
//按照字典序比较
bool cmp(vector<int>& A, vector<int>& B) {
/*
1.先判断位数是否相等
1.1 相等判断高位谁大,直到找到不同的数结束
1.2 高位在最后一位数
2.不相等,直接输出A>=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; //相等结果为0
}
//C=A-B
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); //
if (t < 0) t = 1;
else t = 0;
}
//去掉前导0
while (C.size() > 1 && C.back() == 0) {
C.pop_back();
}
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');
if (cmp(A, B)) {
vector<int> C = sub(A, B);
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
}
else {
vector<int> C = sub(B, A);
printf("-");
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
}
return 0;
}