分析
对于高精度的减法,之前对一会儿要把字符串倒着存进vector,一会儿又要正着从vector拿出来做减法,再然后又倒着进行输出啥的,搞得有点蒙。
但其实认真写过一次代码之后,发现其中是有一定的规则的,且这个规则还不能随意的打破。
我认为这个突破口在做高精减法的那个函数中,由于做减法的时候必须是先低位相减,此时如果你把数字低位存在vector下标高位上,当两个数组a,b长度不一致的时候长度小的数组显然就越界了(b[a.size()-1],b没a这么长就越界了。。。),所以我们必要要把数字的低位放在vector的下标低位上。
因此根据上述的分析,相减的向量要从 低位——>高位
存,这样的话,在把字符串存入vector中的时候就要倒过来存了,因为字符串实际上按下标从小->大
的话,存放的数字的位数是从 高->低
的。
代码
#include<iostream>
#include<vector>
#include<string>
using namespace std;
const int N=1e5+10;
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;//相等的话默认也是A的大
}
vector<int> sub(vector<int> &a,vector<int> &b){
vector<int> c;
int t=0;
//注意这里不能以a.size()-1开头,因为可能b并没有这么长
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;
}
//消除前导0
while(c.size()>1&&!c[c.size()-1])//被减数可能被借位之后,前面的数字变小产生了前导0
c.pop_back();
return c;
}
int main(){
string a,b;
cin>>a>>b;//位数:高->低 字符下标:低—>高
//cout<<a[0]<<" "<<a[1]<<endl;
vector<int> A,B;
//注意这里的vector中低位必须存储的是数字的低位,原因见sub
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中的位数:低->高
vector<int> C;
if(cmp(A,B)){//如果A比B大
C=sub(A,B);
}else{
cout<<"-";
C=sub(B,A);
}
for(int i=C.size()-1;i>=0;i--){
printf("%d",C[i]);
}
return 0;
}