题目描述
给定两个正整数,计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1≤整数长度≤105
输入样例:
32
11
输出样例:
21
算法
模拟人工减法的过程
参考文献
y总讲解视频
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
//比较函数,判断到底是大整数a大还是b大
bool compare(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];
}
//如果都一样那就返回true,也就是两数相等
return true;
}
/*
进行模拟减法的函数,首先要知道我们已经对a,b的大小进行判断
过了,所以这里的第一个参数a是肯定大于第二个参数b的,这样在
下面遍历的时候就会轻松一点
*/
vector<int> sub(vector<int> &a,vector<int> &b){
//答案数组c
vector<int> c;
//对a的长度来进行遍历,t是向高位的进位,0是没有借,1借
for(int i = 0 , t = 0 ; i < a.size() ; i++){
t = a[i] - t;
//当i还在b的长度范围之内,就说明还没有减完
if(i < b.size()) t -= b[i];
/*到这里同位上的相减就完成了。这时就要把t记录的答案
值添加进c总,但是t有可能是小于0 的,所以先+10,再对它
取模,这也就不会是负的,当然如果t本来就是大于0的,那么
+10然后取模其实就是其本身
*/
c.push_back((t + 10) % 10);
//判断一下t是否小于0,小于0就要往前借一位
if(t < 0) t = 1;
//不小于就不用借,继续下一轮的相减
else t = 0;
}
//这里进行的是对0002这类结果的优化,把多余的0删掉
/*当然,如果是11-11=0这种情况,我们还是要保留一位0的。
这里也要注意一点为什么c.back==0,还是要记得我们存储
的时候,先读取的是低位的数,所以高位在后面
*/
while(c.size() > 1 && c.back() == 0 ) c.pop_back();
return c;
}
int main(){
//以字符串进行读取,int读取肯定不够
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;
//比较a,b的大小,确保大的数放在第一个参数上
if(compare(A,B)){
c = sub(A,B);
}else{
c = sub(B,A);
//如果是负数就加一个-号
cout<<'-';
}
//输出
for(int i = c.size() - 1 ; i >=0 ; i--)cout<<c[i];
cout<<endl;
return 0;
}