#高精度减法
思路:和高精度加法一样,用新的数组K保留相同位数相减的结果,用余数r保留每一位的正负,用flag来消除从高位向低位输出时多余的0
代码实现:
`#include<bits/stdc++.h>
using namespace std;
int main()
{
bool flag=false;
int count=0;
string a,b;
cin>>a>>b;
if(a.size()<b.size()||a.size()==b.size()&&a<b)
{
cout<<"-"; //保证a>b,注意这里的负号
swap(a,b);
}
int k[501]={0}; //关于初始化,如果写成全局数组,则默认为0,但是一般不推荐这么做,
int r=0;
int i=a.size()-1;
int j=b.size()-1;
for(;j>=0;j--,i--)
{
k[count++]=(a[i]-'0')-(b[j]-'0')+r; //这里不要注意写成a[i]-b[j]-'0'-'0'+r这样,至于为什么,仔细看看就明白了
if(k[count-1]<0)
{
r=-1; //位数不够,向前借位
k[count-1]=10+k[count-1];
}
else r=0;
}
for(;i>=0;--i)
{
k[count++]=(a[i]-'0'+r); //和加法一样思想,在低位的减法完成后,需要对高位的减法和r做处理,判断是否小于0,至于最高位等于0的情况,下面的代码会处理
if(k[count-1]<0)
{
r=-1;
k[count-1]=10+k[count-1];
}
}
i=count; //k[i]='0',这是一定的,然后从后往前输出
for(;i>=0;--i)
{
if(k[i]>0||flag) //排除了最高位为0的情况
{
cout<<k[i];
flag=true; //只要是最高位不为0,就是true
}
}
if(flag=false) count<<0;
return 0;
}
#高精度乘法
思路:乘法的特点是竖式c[i+j]+=a[i]*b[j],数学原理大家可以自行验证,思路和减法差不多
#include<bits/stdc++.h>
using namespace std;
int c[2001] ; //这里默认值为0,在小程序里推荐大家写成全局变量,不然一个一个赋值会提高时间复杂度,导致可能不能AC
int main()
{
int I=0;
string a, b;
cin >> a >> b;
reverse(a.begin(), a.end()); //reverse函数在algorithm头文件里面,有兴趣的同学可以自行搜索查看,reverse[firsr,last)
reverse(b.begin(), b.end()); //由于reverse针对的是索引,所以说包含左边不包含右边
for (int i=0; i < a.size(); i++)
{
for (int j=0; j < b.size(); j++)
{ //万万没有想到自己当时竟然是把b[j]这里写成了b[i]....(面壁思过)
c[i + j] += (a[i] - 48) * (b[j] - 48); //再利用竖式的特点在每一个数组里面存储相应的元素
}
}
//这里的I最大的size为a.size()+b.size(),你比如10*100=1000,一个i位数乘以一个j位数,最大的结果不过i+j位数,我们只需要按照最大规模来选取,多余的留给后面
for (I = 1; I <= a.size()+b.size(); I++)
{
c[I] += c[I - 1] / 10;
c[I - 1] = c[I - 1] % 10; //注意这里的i从1开始,因为c[i-1]%=10;
}
while (I >= 1 && !c[I]) I--; //为了避免由于输入00***这样的数字出现错误,所以这里用了while,注意这里的I>=1&&!k[I],这就可以不断消除前置的0,和上面的减法其实有异曲同工之妙
for (; I >= 0; I--) //由于上式哪怕只是输入0,也可以保证同样的输出格式
cout << c[I];
return 0;
}