高精度加,减法模版

以前感觉高精度都是大企业开发要考虑的问题,我八百年碰不上呢,结果刚巧昨天看见蓝桥杯的A题就是个高精度的题,直接懵了,这东西就是板子,学过就会,没学过就不会。

主要原理也不难,我们就花两个小时把高精度加减乘除给学了,以后见到直接用了,首先介绍的是高精度加法

高精度算法存在理由是有些大大大数据连longlong都存不下得时候我们就要换种思路曲线救国,虽然数字位数比较有限,但是数组能开的很大啊,所以高精度的核心就是用数组模拟我们运算的过程

这里直接把高精度加法的模版给出

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int A[N],B[N],C[N];//A.B分别表示两个加数,C表示和
int Add(int a[],int b[],int c[],int cntc){/*暂时让c的位数等于a,b中大的那个,若最后有进位特殊处理*/
    int jinwei=0;记录进位
    for(int i=1;i<=cntc;i++){
        jinwei=jinwei+a[i]+b[i];/*其实是暂时存一下个位加进位的和是多少,自己模拟你怎么算加法的*/
        c[i]=jinwei%10;//当前位只能存和的个位,有十位的时候进位
        jinwei=jinwei/10;//对十位上的数记录其进位到下一位上用
    }
    if(jinwei==1) c[++cntc]=1;//循环结束jinwei不为零,代表最高位有进位,c再开一位
    return cntc;//返回c真实的位数
}
int main(){
    string a,b;
    cin>>a>>b;
    /*接下来将字符串逐个字符转化插入到数组中,由于存在进位的问题(后面的数影响前面,前面不影响后面),所以我们倒序读入我们的大数字*/
    int cnta=0;//代表a的位数
    for(int i=a.size()-1;i>=0;i--){
        A[++cnta]=a[i]-'0';
    }
    int cntb=0;//b的位数
    for(int i=b.size()-1;i>=0;i--){
        B[++cntb]=b[i]-'0';
    }
    int cntc=Add(A,B,C,max(cnta,cntb));/*将A,B,C数组读进去,由于c的位数一定大于a,b位数的最大的(等于a,b中大数的位数或者位数加一,我们从函数中去看具体怎么搞)*/
    //倒序输出c
    for(int i=cntc;i>0;i--){
        cout<<C[i];
    }
}

在这个思想之上,我们用vector替代数组,简化代码的同时统一一下高精度算法模版的风格(由于减法中传入数组的size会出问题),由于是应用场景特化的模版,直接背就行,而且模版越简单,风格越统一越好记

#include <bits/stdc++.h>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B){
    if (A.size()<B.size()) return add(B,A);
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t+=A[i];
        if(i<B.size()) t+=B[i];
        C.push_back(t % 10);
        t/=10;
    }
    if(t==1) C.push_back(1);
    return C;
}

int main(){
    string a,b;
    vector<int> A,B,C;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i] - '0');
    C=add(A,B);
    for(int i=c.size()-1;i>=0;i--) cout << C[i];
    return 0;
}

减法和加法几乎一样,有三点要特别注意一下

1.减法的借位处理       2.结果为负数的情况       3.前导0的处理

这里直接给出代码

#include <bits/stdc++.h>
using namespace std;
bool check(vector<int> &A, vector<int> &B){
    if(A.size()!= B.size()) return 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> miu(vector<int> &A, vector<int> &B,vector<int> &C){
    int t=0; //借位
    for(int i=0; i<A.size();i++){
        t=A[i]-t;
        if(i<B.size()) t=t-B[i];
        //不借位(1+10)%10=1 , 借位(-1 + 10) % 10 = 9
        C.push_back((t+10)%10);
        if(t<0) t=1;
        else t=0;
    }
    //针对前导0的情况
    while(C.size()>1&&C.back()==0) C.pop_back();
    return C;
}
int main(){
    string a, b;
    vector<int> A,B,C;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i --) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i --) B.push_back(b[i]-'0');
    if(check(A, B)){
        C = miu(A,B,C);
        for(int i=C.size()-1;i>=0;i--) cout<<C[i];
    }
    else{
        C=miu(B,A,C);
        cout<<"-";
        for(int i=C.size()-1;i>=0;i--) cout<<C[i];
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值