一、算法介绍
与加法类似,从低位开始一位一位减,用t表示A[i]-B[i]-上一次的借位,C[ ]表示结果。每次减有两种情况:
C
[
i
]
=
{
t
,
A
[
i
]
>
B
[
i
]
t
+
10
,
A
[
i
]
≤
B
[
i
]
C[i]=\begin{cases} t,& A[i] > B[i]\\ t +10,& A[i] \le B[i] \end{cases}
C[i]={t,t+10,A[i]>B[i]A[i]≤B[i]
其中第二种情况还产生了一个进位。
ps : 如果A小于B的话,计算B-A,再加上负号即可。
二、代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool cmp(vector<int> &A, vector<int> &B) // 判断是否有 A >= 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相等,也返回true
}
vector<int> sub(vector<int> &A, vector<int> &B) // 加引用相当于取一个别名,可以省去拷贝数组的时间
{
vector<int> C;
int t = 0; // A[i] - B[i] - 上一位的借位(有借位为1,否则为0)
for(int i = 0; i < A.size(); i ++ )
{
t = A[i] - t;
if(i < B.size()) t -= B[i]; // 要判断是否小于B的位数
/* 此时t已经是减过之后的结果 */
// t两种情况:
// 如果t >= 0,C[i] = t
// 否则,C[i] = t + 10,且此时有借位
C.push_back((t + 10) % 10); // 将两种情况合并起来写
if(t < 0) t = 1; // 小于0,有借位
else t = 0;
}
while(C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉前导0
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');
if(cmp(A, B)) // A >= B
{
auto C = sub(A, B);
for(int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
}
else // A < B
{
auto C = sub(B, A);
printf("-");
for(int i = C.size() - 1; i >= 0; i -- ) cout << C[i];
}
return 0;
}