高精度减法与加法类似,模拟手算竖式减法的过程,核心是借位(borrow)的处理。以及小减大的处理。
基本原理
计算 A - B(假设 A ≥ B,避免出现负数):
- 从最低位(数组下标0)开始,逐位相减。
- 如果当前位
A[i] - borrow - B[i]小于 0,就需要向高位借 1,当前位加 10,并标记借位borrow = 1;否则借位为 0。 - 继续下一位,直到所有位处理完。
- 最后去除结果数组前端多余的零(前导零)。
判断 A ≥ B
- 先比较长度:位数多的数更大。
- 长度相同,从最高位(数组尾部)往低位比较,遇到第一个不相等的位,谁的数字大谁就大。
- 全部相等则两数相等。
vector比较数据大小
// 比较两个小端序大数:返回 true 当且仅当 a >= b
bool greaterOrEqual(const vector<int>& a, const 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; // 相等
}
string比较数据大小(注意前导零)
// 比较两个字符串大数:返回 true 当且仅当 a >= b
bool greaterOrEqual(const string& a, const string& b) {
if (a.size() != b.size()) return a.size() > b.size();
return a > b;
}
代码实现
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 字符串 → 小端序 vector
vector<int> strToVec(const string& s) {
vector<int> v;
for (int i = s.size() - 1; i >= 0; --i)
v.push_back(s[i] - '0');
return v;
}
// 比较两个小端序大数:返回 true 当且仅当 a >= b
bool greaterOrEqual(const vector<int>& a, const 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; // 相等
}
// 高精度减法,要求 a >= b
vector<int> sub(const vector<int>& a, const vector<int>& b) {
vector<int> c;
int borrow = 0; // 借位,值为 0 或 1
for (int i = 0; i < a.size(); ++i) {
int diff = a[i] - borrow;
if (i < b.size()) diff -= b[i];
if (diff < 0) {
diff += 10;
borrow = 1;
} else {
borrow = 0;
}
c.push_back(diff);
}
// 去除前导零(保留至少一位)
while (c.size() > 1 && c.back() == 0) {
c.pop_back();
}
return c;
}
// 输出小端序大数
void printVec(const vector<int>& v) {
for (int i = v.size() - 1; i >= 0; --i)
cout << v[i];
cout << endl;
}
int main() {
string s1, s2;
cin >> s1 >> s2;
vector<int> a = strToVec(s1);
vector<int> b = strToVec(s2);
if (greaterOrEqual(a, b)) {
vector<int> result = sub(a, b);
printVec(result);
} else {
cout << "-";
vector<int> result = sub(b, a);
printVec(result);
}
return 0;
}