/* 功能Function Description: 大数除法 开发环境Environment: DEV C++ 4.9.9.1 技术特点Technique: 版本Version: 作者Author: 可笑痴狂 日期Date: 20120731 备注Notes: 解题方法: 基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个一个减显然太慢,如何减得更快一些呢? 以7546 除以23 为例来看一下:开始商为0。先减去23 的100 倍,就是2300,发现够减3 次,余下646。于是商的值就增加300。 然后用646 减去230,发现够减2 次,余下186,于是商的值增加20。最后用186 减去23,够减8 次,因此最终商就是328。 所以本题的核心是要写一个大整数的减法函数,然后反复调用该函数进行减法操作。 计算除数的10 倍、100 倍的时候, 不用做乘法,直接在除数后面补0 即可。 */ #include<stdio.h> #include<string.h> #define MAX 1000 int a1[MAX+10],a2[MAX+10],ans[MAX+10]; //a1被除数,a2除数,ans存放商。逆序存放 char s1[MAX+10],s2[MAX+10]; //长度为 nLen1 的大整数p1 减去长度为nLen2 的大整数p2 //结果放在p1 里,返回值代表结果的长度 //如不够减返回-1,正好减完返回 0 int Substract(int *p1,int *p2,int len1,int len2) { int i; if(len1<len2) return -1; if(len1==len2) { for(i=len1-1; i>=0;--i) { if(p1[i]<p2[i]) //p1<p2 return -1; else if(p1[i]>p2[i]) //p1>p2 break; } } for(i=0;i<len1;++i)//要求调用本函数确保当i>=len2时,p2[i]=0 { p1[i]-=p2[i]; if(p1[i]<0) { p1[i]+=10; --p1[i+1]; } } for(i=len1-1;i>=0;--i) if(p1[i]) //找到最高位第一个不为0 return i+1; return 0; //全部为0,说明两者相等 } int main() { int n,i,j,len1,len2,temp,nTimes; scanf("%d",&n); while(n--) { scanf("%s%s",s1,s2); memset(a1,0,sizeof(a1)); memset(a2,0,sizeof(a2)); memset(ans,0,sizeof(ans)); len1=strlen(s1); len2=strlen(s2); if(len1<len2) { printf("0\n"); //不够除 continue; } for(i=len1-1,j=0;i>=0;--i) a1[j++]=s1[i]-'0'; for(i=len2-1,j=0;i>=0;--i) a2[j++]=s2[i]-'0'; nTimes=len1-len2; if(nTimes>0) { for(i=len1-1;i>=nTimes;--i) a2[i]=a2[i-nTimes];//朝高位移动 for(;i>=0;--i) a2[i]=0; //低位补零 len2=len1; } for(i=0;i<=nTimes;++i) { //一直减到不够减为止 //先减去若干个 a2×(10 的nTimes次方), //不够减了,再减去若干个 a2×(10 的nTimes-1 次方),...... while((temp=Substract(a1,a2+i,len1,len2-i))>=0) //注意while循环中的括号不能少 { len1=temp; ++ans[nTimes-i];//每成功减一次,则将商的相应位加1 } } for(i=MAX;i>=0&&ans[i]==0;--i);//下面输出结果,先跳过高位0 if(i>=0) for(;i>=0;--i) printf("%d",ans[i]); else printf("0"); printf("\n"); } return 0; }