高精度算法【加减乘除-小白也可以看懂】

虽数看过不如写过,但事实确是这样,之前本人也看过高精度相关的一些博客讲解,看完之后觉得很简单,就没有怎么实操,但是当我过了一段时间真正写的时候,我发现有一部分是写不出来了,虽然很简单,但是在学习这方面,还是亲身经历实操的才好,有一个真实的归感悟

高精度加法:

当我们的数非常大的时候,我们就不能使用整数的加减乘除了,我们需要通过其他的方法来实现超大数的加减乘除,这个方法我们就称为高精度,本质上就是通过数组来模拟实现的,将里面的每一个数放到我们的数组当中从而实现加减乘除

正常整数的加减乘除是从右向左来进行操作的,所以在我们的计算当中,我们也要从最右边开始算起,所以在我们存入数组的时候,我们需要倒序放入

  • a是我们的第一个字符串存入的数组
  • b是我们的第二个字符串传入的数组
    for(int i=s1.size()-1;i>=0;i--) a.push_back(s1[i]-'0');
    for(int i=s2.size()-1;i>=0;i--) b.push_back(s2[i]-'0');

 我们在进行数组的加减乘除的时候,从坐标0时进行遍历的,然后开始进行个位数的加法,如果大于10,我们就把这两个数相加的和%10的数加上,赋值到一个新的数组当中,但是我们会出现一个进位的情况,这里我们就需要定义一个变量,来表示我们的进位,当有进位的时候我们也加上,然后更新下一步的进位t/=10

for(int i=0;i<a.size();i++){
        t+=a[i];
        if(b.size()>i) t+=b[i];
        ans.push_back(t%10);
        t/=10;
    }
if(t>0) ans.push_back(1);
#include<bits/stdc++.h>
using namespace std;
vector<int> getAdd(vector<int>& a,vector<int>& b){
    if(a.size()<b.size()) return getAdd(b,a);
    vector<int> ans;
    int t=0;
    for(int i=0;i<a.size();i++){
        t+=a[i];
        if(b.size()>i) t+=b[i];
        ans.push_back(t%10);
        t/=10;
    }
    if(t>0) ans.push_back(1);
    return ans;
}
int main(){
    string s1,s2;
    cin>>s1>>s2;
    vector<int> a,b;
    for(int i=s1.size()-1;i>=0;i--) a.push_back(s1[i]-'0');
    for(int i=s2.size()-1;i>=0;i--) b.push_back(s2[i]-'0');
    vector<int> c=getAdd(a,b);
    for(int i=c.size()-1;i>=0;i--){
        cout<<c[i];
    }
    return 0;
}

高精度减法:

这里先通过判断两个数的大小,再进行相减的,然后如果判断第一个数比第二个数小的时候,进行输出的时候,使用方法的时候,将大的数放在第一个参数的位置上,然后先输出一个“-”号,再输出自己的结果,这个判断比较简单,这里我就不解释了,然后在进行两个数组相减的时候,其实和两数相加差不多,思路是一样的,只不过是从两个数相加变成了相减,然后进位再加法中是被加的,在减法当中是被减的

#include<bits/stdc++.h>
using namespace std;
bool cmp(vector<int>& a,vector<int>& b){
    if(a.size()!=b.size()) return a.size()>b.size();
    if(a.size()==b.size()){
        for(int i=a.size()-1;i>=0;i--){
            if(a[i]!=b[i]){
                return a[i]>b[i];
            }
        }
    }
    return true;
}
vector<int> getSub(vector<int>& a,vector<int>& b){
    vector<int> ans;
    int t=0;
    for(int i=0;i<a.size();i++){
        t=a[i]-t;
        if(b.size()>i) t-=b[i];
        ans.push_back((t+10)%10);
        if(t<0) t=1;
        else t=0;
    }
    //去除前导0
    while(ans.size()>1&&ans.back()==0) ans.pop_back();
    return ans;
}
int main(){
    string s1,s2;
    cin>>s1>>s2;
    vector<int> a,b;
    for(int i=s1.size()-1;i>=0;i--) a.push_back(s1[i]-'0');
    for(int i=s2.size()-1;i>=0;i--) b.push_back(s2[i]-'0');
    vector<int> c;
    if(cmp(a,b)){
        c=getSub(a,b);
    }else{
        c=getSub(b,a);
        cout<<"-";
    }
    for(int i=c.size()-1;i>=0;i--){
           cout<<c[i];
    }
    
    return 0;
}

高精度乘法(高精度×低精度):

使用高精度实现我们的乘法,其实只需要遍历我们的一个数组,就是长度最长的那个,然后让他的每一位×我们的低精度整数,这个和我们的高精度加法很相似,就是一个是加一个是×的关系,最后我们还要前导0,可以使用容器中的一些方法,比如back(),它的作用就是获得最后一个,然后pop_back()删掉最后一个数,我们就遍历我们最后得到的结果,然后进行遍历,删除前导0

#include<bits/stdc++.h>
using namespace std;
vector<int> getMul(vector<int>& a,int b){
    vector<int> ans;
    int t=0;
    for(int i=0;i<a.size();i++){
        t=t+a[i]*b;
        ans.push_back(t%10);
        t/=10;
    }
    if(t) ans.push_back(t);
    while(ans.size()>1&&ans.back()==0) ans.pop_back();
    return ans;
}
int main(){
    string s1;
    int s2;
    cin>>s1>>s2;
    vector<int> a,b;
    for(int i=s1.size()-1;i>=0;i--) a.push_back(s1[i]-'0');
    vector<int> c=getMul(a,s2);
    for(int i=c.size()-1;i>=0;i--){
        cout<<c[i];
    }
    return 0;
}

高精度除法(高精度/低精度):

 高精度除法实现也很简单,但是我们是从前往后进行除法的,所以进行字符串转我们的数组,不需要进行倒序插入,然后直接开始遍历我们的a数组,开始➗我们的b,如果说获得的数太小,我们就插入0,t/b来实现,然后我们还要存储我们的余数t,用到下一次➗b中 

#include<bits/stdc++.h>
using namespace std;
vector<int> getDiv(vector<int>& a,int b){
    vector<int> ans;
    int t=0;//表示余数
    for(int i=0;i<a.size();i++){
        t=t*10+a[i];
        ans.push_back(t/b);
        t%=b;
    }
    reverse(ans.begin(),ans.end());
    while(ans.size()>1&&ans.back()==0) ans.pop_back();
    ans.push_back(t);
    return ans;
}
int main(){
    string s1;
    int s2;
    cin>>s1>>s2;
    vector<int> a,b;
    for(int i=0;i<s1.size();i++) a.push_back(s1[i]-'0');
    vector<int> c=getDiv(a,s2);
    for(int i=c.size()-2;i>=0;i--){
        cout<<c[i];
    }
    cout<<endl;
    cout<<c[c.size()-1];
    return 0;
}

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值