高精度减法
模板适用的前提
计算A-B的时候,当A的位数和B的位数都很大的时候,它就派上用场了。通用的模板有一下几个条件:
1:A和B都是正数
2:A>=B;
疑问???当A和B中有负数的时候,我们是不是不能采用这个模板呢?
其实这并不是模板的问题,而是我们在读入数据的时候我们需要分类讨论,以下就是分类讨论的几种情况:
{
−
(
∣
A
∣
+
∣
B
∣
)
A
<
0
,
B
>
0
A
<
0
,
B
<
0
{
−
(
∣
A
∣
−
∣
B
∣
)
∣
A
∣
>
∣
B
∣
∣
B
∣
−
∣
A
∣
∣
A
∣
<
∣
B
∣
∣
A
∣
+
∣
B
∣
A
>
0
,
B
<
0
\begin{cases} -(|A|+|B|)\quad A<0,B>0\\ A<0,B<0\begin{cases} -(|A|-|B|)\quad |A|>|B|\\ |B|-|A|\quad |A|<|B| \end{cases}\\ |A|+|B| \quad A>0,B<0 \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧−(∣A∣+∣B∣)A<0,B>0A<0,B<0{−(∣A∣−∣B∣)∣A∣>∣B∣∣B∣−∣A∣∣A∣<∣B∣∣A∣+∣B∣A>0,B<0
如果A<B那该怎么办呢???
这时我们只需要计算 B − A B-A B−A,然后在答案面前添加一个负号就行。
如何比较A和B
1:比较A的位数和B的位数,如果两个数的位数不相同的话,就判断一下A的位数是否大于B的位数;
2:如果两个数的位数是相同的话,我们就分别从两个数的高位开始相比较,如果这一位不相同的话,就判断一下A的这一位是否大于B的这一位;
3:如果最后A和B相等的话,直接返回true;
如何计算A-B(模拟人工做减法)
我们用
t
t
t 来表示借位,刚开始做减法的时候
t
=
0
t=0
t=0.
A
i
−
B
i
=
{
A
i
−
B
i
A
i
≥
B
i
A
i
−
B
i
+
10
A
i
<
B
i
A_i-B_i= \begin{cases} A_i-B_i \quad A_i\geq B_i\\ A_i-B_i+10 \quad A_i<B_i \end{cases}
Ai−Bi={Ai−BiAi≥BiAi−Bi+10Ai<Bi
当时这个公式还是不完整的,我们并没哟考虑上一位的借位,所以我们还需要将公式来修正一下
A
i
−
B
i
−
t
=
{
A
i
−
B
i
−
t
A
i
≥
B
i
A
i
−
B
i
+
10
−
t
A
i
<
B
i
A_i-B_i-t= \begin{cases} A_i-B_i-t \quad A_i\geq B_i\\ A_i-B_i+10-t \quad A_i<B_i \end{cases}
Ai−Bi−t={Ai−Bi−tAi≥BiAi−Bi+10−tAi<Bi
最后,如果t<0,表示上一位从这里借了1位,否则就是没有借位。
t
=
{
1
t
<
0
0
t
≥
0
t= \begin{cases} 1 \quad t<0\\ 0 \quad t\geq 0 \end{cases}
t={1t<00t≥0
最后要注意的是输出的答案含有前导零,比如
100
−
97
=
003
100-97=003
100−97=003, 他输出的位数是根据被减数的位数来的,所以我们记得要去掉前导零,当时假如答案就是零的话,我们就不能将它去掉,这个零将会被保留下来。
代码
#include<iostream>
#include<vector>
#include<string>
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;
}
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;
}
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--)
cout << c[i];
cout << endl;
}
else {
auto c = sub(b, a);
cout << "-";
for (int i = c.size() - 1; i >= 0; i--)
cout << c[i];
cout << endl;
}
return 0;
}