题目来源:
http://bailian.openjudge.cn/practice/2737/
描述
求两个大的正整数相除的商。
输入
第1行是被除数,第2行是除数。每个数均不超过100位。
输出
一行,相应的商的整数部分
样例输入
2376
24
样例输出
99
题意描述:
计算位数不超过200的两个大整数的商
解题思路:
总体用减法来模拟除法,当然为了让模拟更高效采用一定的方法。
先将被除数和除数分别存进一维字符数组str1和str2
如果被除数的长度小于除数的,直接输出0
逆置str1和str2存进数组a和b
调用jiandeshang()函数先试减一次,如果返回值小于零,输出零表示长度大于等于情况下 不够减;等于零则 正好够减,意即刚好减数和被减数相等
如果返回值大于零,结果数组的首位元素加一,表示商值加一
将n赋值为被除数和除数相差的数量级个数
如果减过一次除数的被除数的新长度与除数长度差小于零则输出1,表示只够减一次,则商为1
如果长度差n大于0则将除数末尾依次补零直到等于l1的长度
进入循环,模拟减法,减得每个数量级的个数存入相应的位权
程序代码:
1 #include<stdio.h> 2 const int N=230; 3 char str1[N],str2[N]; 4 int a[N],b[N],result[N]; 5 #include<string.h> 6 int jiandeshang(int *p1,int *p2,int l1,int l2); 7 void output(int *s); 8 int main() 9 { 10 11 int i,j,k,l1,l2,n; 12 while(scanf("%s%s",str1,str2) != EOF) 13 { 14 l1=strlen(str1); 15 l2=strlen(str2); 16 17 if(l1<l2) 18 { 19 printf("0 ");//除数大于被除数为 20 continue; 21 } 22 23 memset(a,0,sizeof(a)); 24 memset(b,0,sizeof(b)); 25 for(j=0,i=l1-1;i>=0;i--) 26 a[j++]=str1[i]-'0'; 27 for(j=0,i=l2-1;i>=0;i--) 28 b[j++]=str2[i]-'0'; 29 30 l1=jiandeshang(a,b,l1,l2); 31 if(l1<=0) 32 { 33 if(l1<0) { 34 printf("0 ");//第一次减时不够减为 35 continue; 36 } 37 else { 38 printf("1 ");//正好够减商为 39 continue; 40 } 41 } 42 memset(result,0,sizeof(result)); 43 result[0]++; 44 45 n=l1-l2; 46 if(n<0) { 47 printf("1 "); //减过一次不够减商为 48 continue; 49 } 50 else if(n>0) { 51 for(i=l1-1;i>=0;i--) { 52 if(i>=n)//倒着存储当i大于等于n时,将i的位置存i-n的值,否则存0 53 b[i]=b[i-n]; 54 else 55 b[i]=0; 56 } 57 } 58 l2=l1; 59 for(j=0;j<=n;j++) 60 { 61 while( (k=jiandeshang(a,b+j,l1,l2-j)) >=0) {//传递对应的参数 62 l1=k;//更新长度 63 result[n-j]++;//n-j是对应的位权 64 } 65 } 66 output(result);//输出结果时记得处理进位 67 } 68 return 0; 69 } 70 int jiandeshang(int *p1,int *p2,int l1,int l2) 71 { 72 int i; 73 if(l1<l2) 74 return -1; 75 76 bool bLarge=false; 77 if(l1==l2) { 78 for(i=l1-1;i>=0;i--) { 79 if(p1[i]>p2[i]) 80 bLarge=true; 81 else if(p1[i]<p2[i]) { 82 if(!bLarge) 83 return -1; 84 } 85 } 86 } 87 for(i=0;i<l1;i++) { 88 p1[i] -= p2[i]; 89 if(p1[i]<0) { 90 p1[i] += 10; 91 p1[i+1]--; 92 } 93 } 94 for(i=l1-1;i>=0;i--) 95 if(p1[i]) 96 return i+1;//返回长度加1 97 return 0; 98 } 99 100 void output(int *s) 101 { 102 int i,j; 103 for(i=0;i<N;i++) 104 { 105 if(s[i]>=10) 106 s[i+1] += s[i]/10; 107 s[i] %= 10; 108 } 109 for(i=N;i>=0;i--) 110 if(s[i] != 0) 111 break; 112 113 for(j=i;j>=1;j--) 114 printf("%d",s[j]); 115 printf("%d ",s[0]); 116 }
易错分析:
1、注意结果数组的数组下标
2、各种特殊情况的考虑