2737 大整数除法

Posted Reqaw’s Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2737 大整数除法相关的知识,希望对你有一定的参考价值。

题目来源:
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\n");//除数大于被除数为
 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\n");//第一次减时不够减为
 35             continue;
 36             }
 37             else {
 38                 printf("1\n");//正好够减商为
 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\n"); //减过一次不够减商为
 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\n",s[0]);
116  }

 

易错分析:
1、注意结果数组的数组下标
2、各种特殊情况的考虑

以上是关于2737 大整数除法的主要内容,如果未能解决你的问题,请参考以下文章

大整数的有底除法和欧几里得除法

大整数除法表示为 C++ 中的字符串

试除法分解大整数

大整数除法 - Knuth 算法 D

什么是疯狂大整数除法的最快算法?

STM32单片机算法指令?