高精度除法 精简版

高精度除法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;
}

猜你喜欢

转载自blog.csdn.net/qq_43710979/article/details/89462326