1. 高精度加法
给定两个正整数(不含前导 0),计算它们的和。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1 ≤ 整数长度 ≤ 100000
#include<iostream>
#include<vector>
using namespace std;
//定义高精度假发函数
vector<int> add(vector<int>& A, vector<int>& B) { //通过引用提高效率
vector<int> C;
int t = 0; //定义A和B在某一位的和
for (int i = 0; i < A.size() || i < B.size(); i++) {
//将A和B的对应位加起来赋值给t
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(t); //若t还有则再向前进最后一位
return C;
}
int main() {
string a, b; //由于数据范围较大,所以直接当作字符串进行输入
cin >> a >> b;
vector<int> A, B;
//把输入存入A,B中,并注意所输入的数据类型为int,转化为字符串要 - '0'
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];
}
return 0;
}
2. 高精度减法
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1 ≤ 整数长度 ≤ 10^5
在做减法时有两个注意的点
- 第一是要判断两个数的相对大小,防止出现负值
- 第二是在两个数相减之后得到的数高位可能为零,所以要删去
#include<iostream>
#include<vector>
using namespace std;
//判断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;
}
vector<int> sub(vector<int>& A, vector<int>& B) {
vector<int> C;
int t; //用t表示上一位向当前位的借位,同时表示本位的结果
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); //将结果存储到C中,用(t + 10) % 10来拟合t大于零和小于零的两种情况
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');
}
//A > B时直接输出两者的差值
if (cmp(A, B)) {
auto C = sub(A, B);
for (int i = C.size() - 1; i >= 0; i--) {
cout << C[i];
}
}
//A < B时先输出一个负号再输出相反的差值
else {
auto C = sub(B, A);
cout << "-";
for (int i = C.size() - 1; i >= 0; i--) {
cout << C[i];
}
}
return 0;
}
3.高精度乘法
给定两个非负整数(不含前导 0) A 和 B,请你计算 A×B 的值。
输入格式
共两行,第一行包含整数 A,第二行包含整数 B。
输出格式
共一行,包含 A×B 的值。
数据范围
1 ≤ A的长度 ≤ 100000,
0 ≤ B ≤ 10000
进行高精度减法的思路即为将较小的乘数作为一个整体,进行多位乘一位的运算
#include<iostream>
#include<vector>
using namespace std;
vector<int> mul(vector<int>& A, int b) {
int t = 0;
vector<int> C;
for (int i = 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;
}
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;
}
4. 高精度除法
思路跟减法类似,也是将被除数作为一个整体来进行计算
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int r; //存储余数,同时也存储每一位运算的结果
vector<int> div(vector<int> A, int b) {
vector<int> C;
for (int i = 0; i < A.size(); i++) {
r = r * 10 + A[i]; //每往下循环一次余数都要*10,同时是作为下一位计算时的除数
C.push_back(r / b);
r = r % b;
}
reverse(C.begin(), C.end()); //由于是从高位进行计算所以多余的前置零不在末尾而vector只能弹出末尾所以要转置
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 = 0; i < a.size(); i++) A.push_back(a[i] - '0'); //由于除法的操作是从高位开始所以按顺序存储
auto C = div(A, b);
for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; //由于在函数中为了消去前置0将数组转置了所以在此处还是要倒着输出
cout << endl << r;
return 0;
}