#高精度减法 思路:和高精度加法一样,用新的数组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; }