来分享一下高精度减法的算法。
思想:高精度减法和加法一样都是模拟人脑进行计算,从个位开始依次做减法,如果得数为正就直接相减,不够就借位加10做减法,同时设置个变量t来保存借位。
注意:与加法不同的是由于我们是用数组模拟的减法运算,所以只能实现大数减小数,当面对小数减大数时得数会是个负数,我们无法处理这个负号。所以当我们进行两个数相减时,要先判断这两个数的大小,如果是大数减小数那么就正常相减,如果是小数减大数则需改变减数与被减数的顺序然后再到结果处加个负号就行。
代码实现:
#include<iostream>
#include<string>
#include<vector>
#define int long long
const int N =1e6+10;
using namespace std;
bool cmp(vector<int> &A, vector<int> &B)//判断A是否大于B
{
if(A.size()!=B.size()) return A.size()>B.size();//如果A的位数大于B,那么A就大于B
for(int i=A.size()-1;i>=0;i--)//如果AB位数一样就从大到小依次比较每位的大小
if(A[i]!=B[i])
return A[i]>B[i];
return true;//相等的话也可直接返回
}
vector<int> sub(vector<int> &A, vector<int> &B)//减法函数
{
vector<int>c;//创建答案数组
for(int i=0,t=0;i<A.size();i++)
{
t=A[i]-t;//用t保存相减的答案同时储存借位
if(i<B.size())t-=B[i];//判断是否减完B的所有位数
c.push_back((t+10)%10);//(t+10)%10当AB作完相减时可能为正也可能为负,而不伦正负我们只需要t个位上的数字,所以我们就要给t加上10再取余那么就可以保证我们得到的一定是个位上的数字
if(t<0)t=1;//如果t小于零则说明需要借位
else t=0; //否则借位为零
}
while(c.size()>1&&c.back()==0){//当我们作完相减的时候,由于答案是储存到数组里面,当前面的位数减完后并不会消失而是以0储存到数组当中,如果直接输出的话就会产生形如“00123”这种类型的数字,所以我们需要把前面的0消去
c.pop_back();
}
return c;
}
signed 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(A,B);
cout<<"-";
for (int i =c.size() - 1; i >= 0; i -- ) cout << c[i];
cout << endl;
}
return 0;
}