高精度除法(大数除法)

来源:互联网 发布:微软软件销售合同 编辑:程序博客网 时间:2024/05/01 05:33

[问题描述]

给出两个正整数,计算A÷B的值,保证A和B的位数不超过500位。

输入描述

输入两个用空格隔开的正整数。

输出描述

输出A÷B的值。

样例输入

500 2

样例输出

250

[解题思路]

大数除法的实现有两种方式:
1:用a-=b,循环,直到a<b,记下来执行多少次,则为计算结果;
2:模拟现实,我们手算时是怎么算的,程序就怎么写,
假设a={2 4 2 3 1},b={2 3},结果ans={0 0 0 0 0};

计算过程:

扩展b的位数(a.length()-b.lenth()=3;) b={2 3 0 0 0};

①此时a-b>0 故:

a=a-b={0 1 2 3 1}  ans={0 1 0 0 0};

此时a-b<0 b退一位 取b={2 3 0 0};

此时仍是a-b<0 b再退一位  取b={2 3 0} ;

②此时a-b>0 故:     

a=a-b={0 1 0 0 1};     ans={0 1 0 1 0};

此时仍是a-b>0 

a=a-b={0 0 7 7 1};     ans={0 1 0 2 0};

...

a=a-b={0 0 0 8 1};     ans={0 1 0 5 0};

此时 a-b<0 b退一位 取b={2 3}

③此时a-b>0 故:

a=a-b={0 0 0 5 8};     ans={0 1 0 5 1};

...

a=a-b={0 0 0 1 2};     ans={0 1 0 5 3};

此时a-b<0 已经退了3次位数,计算结束。

计算结果1053

  第一种的效率是不可取的,例如计算11111÷1时,方法一要计算11111次,而方法二只需要5次.

[代码实现]

#include<iostream>#include<string>#include<algorithm>#define N 501using namespace std;/*判断a.size 与b.size的关系以及做减法*/int judge(char a[],int a1,char b[],int b1){if(a1<b1)return -1;/*直接用string a和string b比较会更简单*/if(a1==b1) //a.size==b.size && a<b    {        for(int i=a1-1;i>=0;i--)        {             if(a[i] == b[i]) continue;           if(a[i] > b[i])break;           else return -1;        }    }/*减法*/for(int i=0;i<a1;i++){a[i]=a[i]-b[i]+'0';if(a[i]<'0'){a[i]+=10;a[i+1]-=1;}}/*返回被除数a的长度*/for(int i=a1-1;i>=0;i--){if(a[i]!='0')return (i+1);}return 0; /* a=b的情况 */}string division(string a,string b){char ca[N],cb[N];int ans[N];int a_size=a.size(),b_size=b.size();/*初始化*/fill(begin(ca),end(ca),'0');fill(begin(cb),end(cb),'0');fill(begin(ans),end(ans),0);for(int i=0;i<a_size;i++)ca[a_size-i-1]=a[i];for(int i=0;i<b_size;i++)cb[b_size-i-1]=b[i];/*分析部分*/if(a_size<b_size) return "0";int temp_size=judge(ca,a_size,cb,b_size); if(temp_size<0) return "0";if(temp_size == 0) return "1";ans[0]++;/* 减掉一次,商加1 */int diff_size=temp_size-b_size;/* 差几位补几个0 */if(diff_size<0) return "1";else if(diff_size>0){   /*扩充位数,加快除法*/for(int i=temp_size-1;i>=0;i--){if(i>=diff_size)cb[i]=cb[i-diff_size];elsecb[i]='0';}}b_size=temp_size;/*加快除法,高位减起*/for(int j=0;j<=diff_size;j++){int temp;while( (temp=judge(ca,temp_size,cb+j,b_size-j))>=0 ) /*a-b>0 继续*/{temp_size=temp;ans[diff_size-j]++;}}/*处理最后结果进位*/for(int i=0;i<N;i++){if(ans[i]>=10){ans[i+1]+=ans[i]/10;ans[i]%=10;}}/*返回string类型*/string c="";int n=N-1;/*去掉没意义的0*/while(ans[n]==0 && n>0) n-=1;for(int i=n;i>=0;i--)c+=(ans[i]+'0');return c;}int main(){string a,b;while(cin>>a>>b){cout<<division(a,b)<<endl;}return 0;}


1 0