题意
给定两个正整数,计算它们的差,计算结果可能为负数。
正整数长度的范围是1到100000。
分析
1.先把两个数分别倒序存储在数组中,即最低位在最左边,最高位在最右边。
2.判断A和B哪个数更大,如果A大于B,则计算结果是正数;如果A等于B,则
计算结果是0,;如果A小于B,则计算结果是负数。
3.在进行减法运算时,是从最低位开始相减的;如果A在某个数位上的数比B小,
则A向前一个高位借一个1(即相当于当前数位的10);最后再去掉A的前导零。
4.最后倒序输出。
代码
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
//a[N]为输入的第一个数,b[N]为输入的第二个数,c[N]为a[N]减去b[N]的结果
int a[N], b[N], c[N];
//cnt1是a[N]的长度,cnt2是b[N]的长度,cnt3是c[N]的长度
int cnt1, cnt2, cnt3;
//将大的数减去小的数会更容易计算,因此这里需要比较下输入的两个数的大小
//判断是否有A >= B
bool cmp(int a[], int b[]) {
//如果两个数位数不相同,则比较位数
if (cnt1 != cnt2) return cnt1 > cnt2;
//从最高位开始比较两个数的大小
for (int i = cnt1; i >= 1; i--)
if (a[i] != b[i])
return a[i] > b[i];
//比较完所有位置上的数,发现都相同,返回true
return true;
}
//len1为较大的那个数的位数,len2为较小的那个数的位数
int sub(int a[], int b[], int len1, int len2) {
int t = 0;//t为借位的数
//从低位开始相减,当前位置的数不够大,则向更高的那个位置借位
for (int i = 1; i <= len1; i++) {
t = a[i] - t;
if (i <= len2) t -= b[i];//判断b[]是否还有位数可以减
/*下面这行需要注意一下,如果t >= 0,那么(t + 10) % 10还是等于原来的t;
如果t < 0, 那么(t + 10) % 10就等于原来的t加上10*/
c[i] = ((t + 10) % 10);
/*然后更新t,如果t < 0,则说明a[]当前位的数是小于b[]当前位的数,
因此需要向前一位借一个1,相当于给a[]当前位增加了10;
如果t >= 0,则说明a[]当前位的数是大于等于b[]当前位的数,
不需要向前一位借一个1*/
if (t < 0) t = 1;
else t = 0;
}
/*减法运算有可能会产生前导0,因此这里需要去掉前导0;
只要c数组的长度大于1且从最高位开始有连续的0,就去掉这些0*/
while (len1 > 1 && c[len1] == 0) len1--;
//返回相减运算结果的长度
return len1;
}
int main() {
string x, y;
cin >> x >> y;
//将x倒序存储到a[]中
for (int i = x.size() - 1; i >= 0; i--)
a[++cnt1] = x[i] - '0';
//将y倒序存储到b[]中
for (int i = y.size() - 1; i >= 0; i--)
b[++cnt2] = y[i] - '0';
//判断A和B之间的关系
if (cmp(a, b)) {
cnt3 = sub(a, b, cnt1, cnt2);
} else {
cnt3 = sub(b, a, cnt2, cnt1);
cout << '-';
}
for (int i = cnt3; i >= 1; i--)
printf("%d", c[i]);
return 0;
}