高精度减法
一、算法描述
要实现两个高精度数的减法,和高精度加法一样都是模拟竖式计算的过程,主要就是解决以下两个问题。
谁大谁小?
由于这两个数字都很大,但是不知道谁更大,所以要先判断哪个数更大,思路如下:
-
判断这两个数谁的位数更大,位数更大的自然更大。
-
如果位数不相同,从最高位开始往低位遍历,判断两个数字是否相等,更大的那个原本的数字也更大。
-
如果都一样,即默认是前面一个数更大,并不影响后面的操作。
代码如下:
bool cmp(vector<int> &A, vector<int> &B)
{
if (A.size() != B.size()) return A.size() > B.size();
else
for (int i = A.size() - 1; i >= 0; --i)
if (A[i] != B[i])
return A[i] > B[i];
return true;
}
如何计算?
解决了正负问题,现在来解决如何实现大数减小数。
-
这依然是一个模拟问题,思考如何列竖式计算两个数的减法。
-
从小到大遍历第一个数(第一个数不小),
t += A[i]
,如果第二个数在当前位数还有数,减去该数,t -= B[i]
,还有别忘了处理前一位计算可能产生的借位。 -
将计算结果加入到答案数组中,由于
t
有两种情况,t >= 0 || t < 0
,所以可以统一处理:(t + 10) % 10
。 -
当
t < 0
时,就是产生了借位,令t = -1
,方便下一轮处理,否则令t = 0
表示没有产生借位。 -
最后还需要注意,如果两个数差距非常小,即最后的结果产生了很多前导 \(0\) ,此时我们需要消除,因为输出的时候不需要这些前导 \(0\)。
-
但是也要注意如果两个数相等,那么最后的结果是 \(0\) ,要保留最后一个 \(0\)。
经过优化之后代码如下:
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];
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;
}
说明:
- \(|A| + |B|\)可以转化为 \(A + B、A - B、B - A、-(A + B)\) 这四种情况,都是可以用高精度加减法解决的,只需要特殊处理一下输入即可,所以当前讨论的都是正整数。
二、题目描述
给定两个正整数(不含前导 \(0\) ),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
\(1≤整数长度≤10^5\)
输入样例:
32
11
输出样例:
21
三、题目来源
四、源代码
#include <iostream>
#include <vector>
using namespace std;
const int N = 100010;
bool cmp(vector<int> &A, vector<int> &B)
{
if (A.size() != B.size()) return A.size() > B.size();
else
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];
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;
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');
vector<int> C;
if (cmp(A, B)) C = sub(A, B);
else
{
cout << "-";
C = sub(B, A);
}
for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
return 0;
}