C++高精度算法模板(加减乘除)

主函数模板

加减法模板
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a,b;
int main(){
    string s1,s2;
    cin>>s1>>s2;
    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=add(a,b);

    // 减法使用
    if(cmp(a,b))
        c=sub(a,b);
    else {
        cout<<"-";
        c=sub(b,a);
    }
    //-----------------------------------
    for(int i=c.size()-1;i>=0;i--)cout<<c[i];
}
乘除法模板
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int>a;

int main(){
    string s1;
    int num,k;
    cin>>s1>>num;
    for(int i=s1.size()-1;i>=0;i--)a.push_back(s1[i]-'0');
    // 除法使用
    vector<int>c=div(a,num,k);
    // 乘法使用
    vector<int>c=mul(a,num);
    // 公用
    for(int i=c.size()-1;i>=0;i--)cout<<c[i];
    // 除法使用
    cout<<endl<<k;
}

高精度加法(len+len)

算法模拟:若num1=1237,num2=99876,存储的时候a[]={7,3,2,1}.b[]={6,7,8,9,9}

  1. 开始t=0
  2. 第一轮循环t=13,c[]={3},t=1
  3. 第二轮循环t=11,c[]={3,1},t=1
  4. 第三轮循环t=11.c[]={3,1,1},t=1
  5. 第四轮循环t=11,c[]={3,1,1,1},t=1
  6. 第五轮循环t=10,c[]={3,1,1,1,0},t=0
  7. 结束循环,因为t=1,所以继续加入c中,所以c[]={3,1,1,1,0,1}
vector<int> add(vector<int>a,vector<int>b){
    vector<int>c;
    int t=0; // 进位
    for(int i=0;i<a.size()|| i<b.size();i++){  
        if(i<a.size())t+=a[i];   // 若a没有越界,则加上a[i]
        if(i<b.size())t+=b[i];   // 若b没有越界,则加上b[i]
        c.push_back(t%10);		 // 将t的低位加入c中
        t/=10;
    }
    if(t==1)c.push_back(1);   // 判断最大的两个数是否有进位
    return c;
}

高精度减法(len-len)

减法要相对复杂的多,首先需要比较两个数的大小,代码如下

bool cmp(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;   // 位数,每位大小都相同,返回true
}

a>=b,则调用sub(a,b),若a<b,则输出'-1',调用sub(b,a)
sub函数代码如下:

vector<int> sub(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-=b[i];
        c.push_back((t+10)%10);   // 此时t有可能<0,则需要借位,
        // 上述代码等价于
      	//	if(t<0)c.push_back((t+10)%10);
      	//	else c.push_back(t%10);
        if(t<0)t=1;
        else t=0;
    }
    while(c.size()>1 && c.back()==0)c.pop_back();  //去掉前缀0
    return c;
}

算法模拟:若num1=3223,num2=3333,存储的时候a[]={3,2,2,3}.b[]={3,3,3,3}

  1. 开始t=0
  2. 第一轮循环t=0,c[]={0},t=0
  3. 第二轮循环t=1,c[]={0,1},t=0
  4. 第三轮循环t=1,c[]={0,1,1}.t=0
  5. 第四轮循环t=0,c[]={0,1,1,0},t=0
  6. 进入while循环,则c[]={0,1,1}

高精度乘法(len*num)

vector<int> mul(vector<int>a,int num){
    vector<int>c;
    int t=0; // 进位
    for(int i=0;i<a.size()||t;i++){
        
        if(i<a.size())t+=a[i]*num;
        c.push_back(t%10);
        t/=10;
    }
    while(c.size()>1 && c.back()==0)c.pop_back();   //删除前缀0
    return c;
}

算法模拟:若num1=1234,num2=12,存储的时候a[]={4,3,2,1},num=12

  1. 开始t=0
  2. 第一轮循环t=48,c[]={8},t=4
  3. 第二轮循环t=40,c[]={8,0},t=4
  4. 第三轮循环t=28,c[]={8,0,8},t=2
  5. 第四轮循环t=14.c[]={8,0,8,4},t=1
  6. 第五轮循环(a已经越界,但t不为0),t=1,c[]={8,0,8,4,1},t=0
  7. 结束循环直接返回(不需要删除前缀0,一般只有num=0才需要)

高进度除法(len/num)

vector<int> div(vector<int>a,int num,int &k){
    vector<int>c;
    int t=0; // 进位
    for(int i=a.size()-1;i>=0;i--){
        t=t*10+a[i];
        c.push_back(t/num);
        t%=num;
    }                                   
    k=t;
    reverse(c.begin(),c.end());
    
    while(c.size()>1 && c.back()==0)c.pop_back();
    return c;
}

除法与加减乘法不同,可以从高位开始存储,但为了与加减乘法兼容,则这里还是从低位存储,但是计算时候从高位计算
算法模拟:若num1=1234,num2=12,存储的时候a[]={4,3,2,1},num=12

  1. 开始t=0
  2. 第一轮循环t=1,c={0},t=1
  3. 第二轮循环t=12,c={0,1},t=0
  4. 第三轮循环t=3,c={0,1,0},t=3
  5. 第四轮循环t=34,c={0,1,0,2},t=10
  6. 这里也需要去掉前缀0,但是必须先reverse才能去掉前缀和,返回的c正好是倒序
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值