高精度除法真的毒瘤(小声bb)
所谓高精度除法就是用数组模拟大数相除,其主要思路就是用被除数一直减去除数得到相应商位置上的值,具体解释在代码中呈现。
#include <cstdio>
#include <cstring>
#define Maxn 500005
using namespace std;
char s1[Maxn],s2[Maxn];
int a[Maxn],b[Maxn],c[Maxn],t[Maxn];//a表示被除数,b表示除数,c表示商,t表示除数处于与被除数相对应的某一位
int comp(int aa[],int bb[]){//两个数比较大小,若a>b,return 1;若a=b,return 0;若a<b,return -1;
if(aa[0]>bb[0]) return 1;
if(aa[0]<bb[0]) return -1;
for(int i=aa[0];i>=1;i--){
if(aa[i]<bb[i]) return -1;
if(aa[i]>bb[i]) return 1;
}
return 0;
}
void cpy(int aa[],int bb[],int l){//关键的一个操作,给t数组赋值,将除数与被除数的每一位进行对齐
for(int i=1;i<=aa[0];i++) bb[i+l-1]=aa[i];
bb[0]=aa[0]+l-1;
}
int main(){
scanf("%s%s",s1+1,s2+1);
int la=strlen(s1+1);
int lb=strlen(s2+1);
for(int i=1;i<=la;i++){
a[i]=s1[la-i+1]-'0';
}
a[0]=la;
for(int i=1;i<=lb;i++){
b[i]=s2[lb-i+1]-'0';
}//倒序存储,下标为0的位置存储长度
b[0]=lb;
c[0]=la-lb+1;//c[0]存储商的长度
for(int i=c[0];i>0;i--){
memset(t,0,sizeof(t));
cpy(b,t,i);//如果不清楚t数组可以在这之后输出一下,观察一下就很容易理解
while(comp(a,t)>=0){//如果a>=t
c[i]++;//对应商的位置++
if(!comp(a,t)){
a[0]=0;//一个退出条件,注意与c[i]++顺序,因为最后相等时还有一个除数没有减去,所以要先c[i]++
continue;
}
for(int j=1;j<=a[0];j++){
if(a[j]<t[j]){//如果被除数这一位小于除数这一位,被除数向上一位借位
a[j+1]--;
a[j]+=10;
}
a[j]-=t[j];//被除数减去一个除数
}
while(a[0]>0&&!a[a[0]]) a[0]--;//删去前导零,因为此时倒序存储,所以末尾为前导零
}
}
while(c[0]>0&&!c[c[0]]) c[0]--;//删除商的前导零
for(int i=c[0];i>=1;i--){
printf("%d",c[i]);
}//输出
return 0;
}
此代码实际上模拟的就是竖式除法的过程,每一位商由一次次减去除数++得到,这是此代码的核心。