高精度除法並計算除餘數(綜合高精減法和加法)
阿新 • • 發佈:2019-02-01
Description
高精除以高精
Input
每組測試資料個棧2行,每行代表一個高精度整數(不超過100位)
Output
每組測試資料輸出佔2行,分別輸出商和餘數。
Sample Input
140
5
Sample Output
28
0
思路:
除法就是模擬減法。
先算出可以從被除數減去除數的最大倍數(此倍數由10^k表示),然後依次減去10^(k-1),10(k-2)倍,,,,直到不夠減。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
char aa[109],bb[109];
int a[109],b[109],ans[109];
int len1,len2;
void init()
{
len1=strlen(aa);
len2=strlen(bb);
memset(a,0,sizeof a);
memset(b,0,sizeof b);
memset(ans,0,sizeof ans);
for(int i=len1-1,j=0; i>=0; i--,j++)
a[j]=aa[i]-'0';
for(int i=len2-1,j=0; i>=0; i--,j++)
b[j]=bb[i]-'0' ;
}
void output()
{
//cout<<"*************\n";
int len=strlen(aa);
for(int i=0; i<len; i++)//輸出之前還要處理進位,由於我們的結果時每減一次除數的相應倍數,然後加出來的
ans[i+1]+=ans[i]/10,ans[i]%=10;
int i=len-1;
int flag=0;
while(ans[i]==0)i--;
if(i>=0) flag=1;
for(; i>=0; i--)
cout<<ans[i];
if (!flag) cout<<"0";
cout<<endl;
i=len-1;
flag=0;
while(a[i]==0) i--;
if(i>=0) flag=1;
for(; i>=0; i--)//剩下的a 中儲存的就是餘數
cout<<a[i];
if(!flag) cout<<"0";
cout<<endl;
// cout<<"*************\n";
}
int cmp(int *p1,int *p2,int len1,int len2)//比較兩個數的大小
{
if(len1<len2) return -1;
else if(len1==len2)
{
for(int i=len1-1; i>=0; i--)
if(p1[i]>p2[i]) return 1;
else if(p1[i]<p2[i]) return -1;
return 0;
}
else return 1;
}
int sub(int *p1,int *p2,int len1,int len2)
{
// cout<<"-----------------\n";
// for(int i=len1-1; i>=0; i--) cout<<p1[i];
// cout<<endl;
// for(int i=len2-1; i>=0; i--) cout<<p2[i];
// cout<<endl;
// cout<<"-----------------\n";
if(cmp(p1,p2,len1,len2)==-1) return -1;//返回-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]) return i+1;//返回的是被除數還剩下多少位
return 0;
}
void solve()
{
init();
len1=sub(a,b,len1,len2);
if(len1<0)//不夠減
{
cout<<"0"<<endl;
for(int i=strlen(aa)-1; i>=0; i--)
cout<<a[i];
cout<<endl;
return;
}
ans[0]++;//先直接減了一次,所以結果要加一
int k=len1-len2;
if(k<0)
{
output();
return;
}
else if(k>0)//試探出可以減的最大倍數10^K
{
for(int i=len1-1; i>=0; i--)//在除數後面增加零的個數,變成它的10^k倍
{
if(i>=k)
b[i]=b[i-k];
else b[i]=0;
}
}
// cout<<"k="<<k<<endl;
len2=len1;//注意此時的被除數的長度變了!
for(int j=0; j<=k; j++)//依次減去10^(k-1),10(k-2),,,,10^0倍
{
int tmp;
while((tmp=sub(a,b+j,len1,len2-j))>=0)一直減,知道不能減了,注意傳引數的技巧!!!第二個引數說明此時的除數為原來除數的10^(k-j)倍
{
len1=tmp;
ans[k-j]++;
}
}
output();
}
int main()
{
while(cin>>aa>>bb)
{
solve();
}
return 0;
}