算法主体来自:http://blog.youkuaiyun.com/jarily/article/details/8623810,我做了一些错误的改正以及加了一些注释。最后,把C风格改成了C++风格(我真无聊....)。
算法思想:反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。所以算法核心是写一个大整数的减法函数,反复调用该函数进行减法操作。
算法步骤:用数组a表示被除数,数组b表示除数,数组res表示商;先用被除数a减去除数b得到差的位数k,同时商+1,再用被除数a减去若干个除数b*(10^k),不够减了,再减去若干个除数b*(10^(k-1))...b*(10^(k-2))...,一直减到不够减为止;每成功减一次,则商的相应位+1;最后再循环处理商的进位问题。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdlib>
using namespace std;
const int N=1000;
int a[N],b[N],res[N*2];
char x[N],y[N];
int len1,len2;
void init()
{
len1=strlen(x);
len2=strlen(y);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(res,0,sizeof(res));
for(int i=len1-1,j=0; i>=0; i--) //将被减数转为数字倒序存储在数组中,便于进行计算
{
a[j++]=x[i]-'0';
}
for(int i=len2-1,j=0; i>=0; i--) //将减数转为数字倒序存储在数组中,便于进行计算
{
b[j++]=y[i]-'0';
}
}
int substraction(int *p1,int *p2,int len1,int len2)//计算长度为len1的大整数减去长度为len2的大整数的结果的长度
{ //减的结果放在数组p1中,不够返回-1,正好返回0
if(len1<len2)
return -1;
bool flag=0;
if(len1==len2)//若两数长度相等,一位位判断大小
{
for(int i=len1-1; i>=0; i--)
{
if(p1[i]>p2[i])
flag=1;
else if(p1[i]<p2[i])
{
if(!flag)
return -1;
}
}
}
for(int i=0; i<len1; i++)//减法
{
p1[i]-=p2[i];
if(p1[i]<0)
{
p1[i]+=10;
p1[i+1]--;
}
}
for(int i=len1-1; i>=0; i--)
{
if(p1[i]) //光标遍历至非零处(忽略开头的0)
return i+1; //返回最高位非零位的前一位位置,即新的被减数长度
}
return 0;
}
void output()
{
for(int i=0; i<N; i++) //进位
{
if(res[i]>=10)
{
res[i+1]+=res[i]/10;
res[i]%=10;
}
}
bool flag=0;
for(int i=N-1; i>=0; i--)//输出
{
if(flag)
{
cout<<res[i];
}
else if(res[i]) //遇到第一个非零数才开始输出操作
{
cout<<res[i];
flag=1;
}
}
if(!flag) //如果一直都是0,就输出一个0
cout<<0;
cout<<endl;
}
void solve()
{
init();
len1=substraction(a,b,len1,len2);//被减数减去减数后得到的差为新的被减数,得到新的被减数长度
if(len1<0)
{
cout<<0<<endl;
return;
}
else if(len1==0)
{
cout<<1<<endl;
return;
}
res[0]++;//减掉一次了,商+1
int k=len1-len2;
if(k<0)//减一次后不能再减了
{
output();
return;
}
else if(k>0)//将数组b乘以10的某次幂(通过使数组整体左移动,后端添0实现),使得其长度与数组a相同
{
for(int i=len1-1; i>=0; i--)
{
if(i>=k)
b[i]=b[i-k];
else
b[i]=0;
}
}
len2=len1;
for(int j=0; j<=k; j++)//先减去若干个b*(10^k),不够减了再减去若干个b*(10^(k-1))...
{
int temp;
while((temp=substraction(a,b+j,len1,len2-j))>=0)//一直减到不够减为止
{
len1=temp;
res[k-j]++;//每成功减一次,则商的相应位+1
}
}
output();
}
int main()
{
cin>>x>>y;
solve();
system("pause");
return 0;
}