C++完整参考代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 比较两个非负整数:a >= b 返回 true
bool ge(const string& a, const string& b) {
if (a.size() != b.size()) return a.size() > b.size();
return a >= b;
}
// 高精度减法,要求 a >= b;倒序存位,返回同样倒序的结果
vector<int> sub(const vector<int>& a, const vector<int>& b) {
vector<int> c;
int borrow = 0; // 借位
for (size_t i = 0; i < a.size(); i++) {
int t = a[i] - borrow - ((i < b.size()) ? b[i] : 0);
if (t < 0) { t += 10; borrow = 1; } // 不够减,向高位借 1
else { borrow = 0; }
c.push_back(t);
}
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 = (int)A.size() - 1; i >= 0; i--) a.push_back(A[i] - '0');
for (int i = (int)B.size() - 1; i >= 0; i--) b.push_back(B[i] - '0');
vector<int> c;
if (ge(A, B)) {
c = sub(a, b); // A >= B,直接相减
} else {
cout << "-"; // A < B,先输出负号
c = sub(b, a);
}
for (int i = (int)c.size() - 1; i >= 0; i--) cout << c[i];
cout << endl;
return 0;
}
答案:读入两个可能长达 500 位的整数 A、B,输出 A − B(可为负)。验证:A=1000、B=1 → 输出 999;A=1、B=1000 → 输出 -999;A = B → 输出 0(去前导零后保留一个 0)。
思路:分三步走。第一步比较大小:先比位数,位数多的更大;位数相同时按字符串字典序比较即可(因为都是同样的数字字符)。第二步定符号:若 A ≥ B 就正常算,否则先输出一个负号,再算 B − A。第三步在高精度 sub 里模拟竖式减法:从低位往高位,某一位不够减就向高位借 1(本位加 10、borrow 记 1)。减完记得把高位多余的 0 去掉,全是 0 时保留一个 0。
考点:高精度减法的「借位」实现;大整数的大小比较;负数结果的符号处理;前导零的清除(与加法最大的不同点)。
易错:① 忘记比较大小就直接 sub(a,b),会算出错误结果或下溢;② 借位忘记在下一轮扣掉,或者是先把 a[i] 减了再判断正负;③ 去前导零时把结果 0 也删空,要用 while (c.size() > 1 && c.back() == 0) 兜住;④ 比较时直接比字符串长度就下结论,位数相同的情况没处理;⑤ 结果位数可能和 a 相同,用 a 的长度定循环上界即可。