高精度加法
高精度加法归根结底是一个模拟人工加法的过程
大致要点如下
Ⅰ.使用两个数组a,b倒序存储输入的数字,这样能比较方便地处理进位问题
Ⅱ.在进行加法地过程中,使用一个指针 i 指向当前正在相加的位置,并开一个t变量存储进位
Ⅲ.如果a[i]或b[i]存在,就使得t加上 a[i]或b[i]
Ⅳ.向结果数组c中加入t%10
Ⅴ.t=t/10 完成进位,为下一轮运算的进位作准备
Ⅵ.(易错)在循环相加各个位之后,t中仍然可能有残余的数字没有加入到结果数组中,如50 + 50 这种场景,循环后c数组中为00,t为1,所以需要手动添加剩余的值。
实现代码:
vector<int> add(vector<int> a,vector<int> b)
{
int t=0;
vector<int> c;
for(int i=0;i<a.size()||i<b.size();i++)
{
if(i<a.size()) t+=a[i];
if(i<b.size()) t+=b[i];
c.push_back(t%10);
t/=10;
}
if(t)
c.push_back(t);
return c;
}
高精度减法
高精度减法也是一个模拟人工减法的过程,但是减法有可能出现负数,实现起来比高精度加法复杂
大致分为以下几个过程
比较两个数组谁更大
实现如下:
bool cmp(vector<int> &a,vector<int> &b)
{
/*位数多的大*/
if(a.size()!=b.size())
return a.size()>b.size();
/*位数相同则逐位比较*/
for(int i=0;i<a.size();i++)
if(a[i]!=b[i])
return a[i]>b[i];
/*经历了上面两步都还没有返回,说明相等,直接return*/
return true;
}
较大的a[]和较小的b[],进行高精度减法
Ⅰ.需要开一个int t 来记录之前是否有过借位
Ⅱ.每次运算,分够不够减两种情况
如
A3 A2 A1 A0
- B2 B1 B0
----------------------
|--- if(Ai-Bi>=0) Ai-Bi-t
对于每个Ai-Bi-t分两种情况 |
|---if(Ai-Bi<0) Ai-Bi+10-t (需要借一位)
vector<int> mine(vector<int>& a, vector<int> &b)
{
vector<int> c;
for(int i=0,t=0;i<a.size();i++)
{
//进位
t=a[i]-t;
if(i<b.size()) t-=b[i]; //由于b较小,可能没有第i位,所以在减b之前判断
c.push_back((t+10)%10); //两种情况合二为一写
/*
如果 t (或者说a[i]-b[i]-t)< 0 这种情况需要借位 体现在本轮循环,即push_back(t+10) 并在循环后使t为1
如果 t (或者说a[i]-b[i]-t)> 0 这种情况无需要借位 体现在本轮循环中,即是push_back(t) 并在循环后使t为0
这两种情况都能合二为一地写成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;
}