1. 程式人生 > >高精度除法並計算除餘數(綜合高精減法和加法)

高精度除法並計算除餘數(綜合高精減法和加法)

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; }