存储方式:
- 使用字符串、数组存储
- 从低位到高位依次存放, 即string[0] 存放个位
创建: 将字符串转换成数组
string x, y;
vector<int> a, b;
cin >> x >> y;
for(int i = x.length() - 1; i >= 0; i--) a.push_back(x[i] - '0');
for(int i = y.length() - 1; i >= 0; i--) b.push_back(y[i] - '0');
输出函数
void display(string s) {
for(int i = s.length() - 1; i >= 0; i--)
printf("%c", s[i]);
puts("");
}
高精度加法: 两个大数相加
思路:
- 模拟列竖式加法,使用中间变量t,将t的个位上的数存入答案数组
代码模板
vector<int> add(vector<int> &a, vector<int> &b) {
vector<int> ans;
for(int i = 0, t = 0; i < a.size() || i < b.size(); i++) {
if(i < a.size()) t += a[i];
if(i < b.size()) t += b[i];
ans.push_back(t % 10);
t /= 10;
}
if(t) ans.push_back(1);
return ans;
}
高精度减法: 两个大数相减
思路:
- 判断结果的正负,如果前者大于后者结果为正,否则计算后者减前者,再加上一个负号
代码模板
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> ans;
// 通过比较函数已经确定size(a) > size(b)
for(int i = 0,t = 0; i < a.size(); i++) {
t = a[i] - t; // 去掉前者的借位
if(i < b.size()) t -= b[i];
ans.push_back((t + 10) % 10);
if(t < 0) t = 1; // 表示借位
else t = 0;
}
while(ans.size() > 1 && ans.back() == 0) ans.pop_back();
return ans;
}
高精度乘法 :一个很大的数乘以一个很小的数
思路:
- 借用一个中间变量t表示进位,t不为零或者未访问完a数组,循环就一直进行
代码模板
vector<int> mul(vector<int> &a, int b) {
vector<int> ans;
int t = 0;
for(int i = 0; i < a.size() || t; i++) {
if(i < a.size()) t += a[i] * b;
ans.push_back(t % 10);
t /= 10;
}
return ans;
}
高精度除法:一个很大的数除以一个很小的数,返回商和余数
思路
- 模拟列式手算除法, 从高位开始算起,每次将余数乘10,再加上下一位,将r整除b的结果存入答案数组。
- 反转答案数组
- 去掉前导零
代码模板
vector<int> div(vector<int> &a, int b, int &r) {
vector<int> ans;
r = 0;
// 模拟手算除法, 从高位算起
for(int i = a.size() - 1; i >= 0; i--) {
r = r * 10 + a[i];
ans.push_back(r / b);
r %= b;
}
// 按照存储方式,从低位开始存储
reverse(ans.begin(), ans.end());
// 去掉前导零
while(ans.size() > 1 && ans.back() == 0) ans.pop_back();
return ans;
}