【题目来源】
https://www.luogu.com.cn/problem/P2142
https://www.acwing.com/problem/content/794/
【题目描述】
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
【输入格式】
共两行,每行包含一个整数。
【输出格式】
共一行,包含所求的差。
【数据范围】
1≤整数长度≤100000
【输入样例】
32
11
【输出样例】
21
【算法分析】
1.C++不支持大数运算,故而引入高精度算法。
2.高精度减法将大数以字符串形式输入,然后拆分转换为一位一位的整数,之后按照小学的竖式运算方法完成编码。(注意:字符串中0下标从左开始,竖式运算中0下标从右开始,故代码中需要有一个逆序操作。如 a[i]=s1[s1.length()-i-1]-'0';)
3.高精度减法中需判断减数、被减数的大小 --> 若s1、s2是string类型,则用 s1.compare(s2) 来判断s1、s2大小。若s1、s2是字符数组,则用 strcmp(s1,s2) 来判断s1、s2大小。当然,也可以自定义函数来进行判断。
4.高精度减法中需交换减数、被减数 --> 若s1、s2是string类型,则再引入一个字符串t,然后用“t=s1;s1=s2;s2=t;”来完成s1、s2的交换。若s1、s2是字符数组,则再引入一个字符数组t,然后用“strcpy(t,s1);strcpy(s1,s2);strcpy(s2,t);”来完成s1、s2的交换。
5.对最高位做判断,删除前导0,然后输出便得结果。如需对例子1235-1233=0002进行前导0的删除。
【算法代码一】
#include <bits/stdc++.h>
using namespace std;
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;
}
//C=A-B,满足A>=B,A>=0,B>=0
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;
}
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)) {
auto C=sub(A,B);
for(int i=C.size()-1; i>=0; i--) printf("%d",C[i]);
} else {
auto C=sub(B,A);
printf("-");
for(int i=C.size()-1; i>=0; i--) printf("%d",C[i]);
}
return 0;
}
/*
input:
32
11
output:
21
*/
【算法代码二:来源于AcWing 792. 高精度减法 - AcWing】
#include <iostream>
#include <vector>
using namespace std;
const int N = 1000010;
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;
}
void trimZero(vector<int> &A) {
while (A.back() == 0 && A.size() > 1) A.pop_back();
}
vector<int> sub(vector<int> &A, vector<int> &B) {
vector<int> C;
int t = 0;
for (int i = 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;
}
trimZero(C);
return C;
}
int main() {
string a, b;
cin >> a >> b;
vector<int> A, B, C;
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');
trimZero(A), trimZero(B);
if (cmp(A, B)) C = sub(A, B);
else {
C = sub(B, A);
printf("-");
}
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
return 0;
}
/*
input:
56328123678
958729125679
output:
-902401002001
-----------------------
input:
9876543219
123456789
output:
9753086430
*/
【参考文献】
https://www.acwing.com/blog/content/277/
https://www.runoob.com/cplusplus/cpp-strings.html
https://blog.csdn.net/qq_37941471/article/details/82107077
https://blog.csdn.net/justidle/article/details/104426323