高精度除法C++
C++没有自带的大整数类,所以对于大整数的四则运算需要自己写,相对于加减乘,大整数的除法更难,因为大整数的除法基本上包含了大整数的其他四则运算。
一、Solution 1
对于大整数的除法(以A-B为例),首相想到的一种最简单的办法就是不断用A去减B,然后答案+1,直到A小于B就能得到答案了。
这种方法虽然简单,但是对于一些情况会出现致命的缺陷,因为A可以很大并且B可以很小,如果A等于101111,B等于1,虽然只有一千多位,但是要进行101111次运算,算到天荒地老也算不完。
二、Solution 2
对简单的算法进行改进,可以想到模拟手动竖式计算,比如233333-666,可以先把666乘以十的幂次,变成66600(小于233333的最小的666*10k),然后用233333不断减66600直到比66600小为止(233333-3*666*102=33533),这时候每次减法运算之后答案直接加上100就行了,然后不断缩小66600(66600->6660->666),到连666都减不了的时候就可以得到答案了。是对普通算法的优化。
#include<string>
#include<iostream>
using namespace std;
bool big_equ(string &x,string &y){ //判断是否大于等于
if(x.size()!=y.size()) return x.size()>y.size();
else for(int i=0;i<x.size();i++) if(x[i]!=y[i]) return x[i]>y[i];
return true;
}
inline string my_minus(string &x,string &y){ //大数减法
string ans;
int d = x.size()-y.size();
for(int i=0;i<d;i++) ans+=x[i]; //相当于减0
for(int i=0;i<y.size();i++) ans+=x[i+d]-y[i]+'0';
for(int i=ans.size()-1;i>=0;i--) if(ans[i]-'0'<0) ans[i-1]-=1,ans[i] = 10+ans[i]; //退位
int pos=0;
while(ans[pos]=='0'&&pos!=ans.size()-1) pos++; //去除前导零
return ans.substr(pos,ans.size()-pos);
}
void reduce(string &t){t.resize(t.size()-1);}
string Big_integer_div(string x,string y){
string ans,tmpdiv=y;
if(!big_equ(x,y)) return "0";
int pos = 1;
while(tmpdiv.size()<x.size()) tmpdiv.append("0"),pos++;
if(!big_equ(x,tmpdiv)) reduce(tmpdiv),pos--;
int len = pos; //记录答案的位数
for(int i=0;i<len;i++) ans.append("0");
while(big_equ(x,y)){ //还可以除
while(big_equ(x,tmpdiv)) ans[len-pos]+=1,x = my_minus(x,tmpdiv); //把对于10^pos全部减掉
reduce(tmpdiv),pos--;
}
return ans;
}
int main(){
string diva,divb;
cin>>diva>>divb;
cout<<Big_integer_div(diva,divb)<<endl;
return 0;
}