《算法笔记》复习——大整数运算

参考《算法笔记》

在平时编程的过程中,我们能够使用的最大整数表达范围是9223372036854775807,为long long型,当超过了这个范围我们应该如何进行运算呢?

在《算法笔记》中提出用整数型数组进行表示整数的方法,需要注意以下几点:

① 大整数运算,可以使用数组来表示
② 整数的高位存储在数组的高位,整数的低位存储在数组的低位
③ 并且使用len来记录位的长度
④  还要加上构造函数,能够直接初始化
⑤ 通过字符串进行读入,在转存到bign结构体,读入的时候整数高位在字符串低位,因此要倒着赋值

下面让我们来看一下代码:

#include<cstdio>
#include<string.h>
using namespace std;
struct bign{
    int d[10001];
    int len;
    bign(){
        memset(d,0,sizeof(d));
        len = 0;
    }
};
bign change(char str[]){
    bign a;
    a.len = strlen(str);// 碰到'\0'就结束,即刚好等于字符串的长度
    for(int i=0;i<a.len;i++){
        a.d[i] = str[a.len-i-1]-'0';// 对于str的下标,从边界进行考虑是否需要减1,然后得到的是对应的字符,就减'0'
    }
    return a;
}
// 1表示大于,-1表示小于,0表示等于
int compare(bign a,bign b){
    if(a.len>b.len) return 1;
    else if(a.len<b.len) return -1;
    else{
        for(int i=a.len-1;i>=0;i--){
            if(a.d[i]>b.d[i]) return 1;
            else if(a.d[i]<b.d[i]) return -1;
        }
    }
    return 0;
}
bign add(bign a,bign b){
    bign c;
    int flag = 0;
    // 循环一直到最大的数,从低位相加
    for(int i=0;i<a.len||i<b.len;i++){
        int temp = a.d[i]+b.d[i]+flag;
        c.d[c.len++] = temp%10;
        flag = temp/10;
    }

    if(flag!=0){
        c.d[c.len++] = flag;
    }
    return c;
}
bign sub(bign a,bign b){
    bign c;
    for(int i=0;i<a.len||i<b.len;i++){
        // 小于就要借位
        if(a.d[i]<b.d[i]){
            a.d[i+1]--;
            a.d[i]+=10;
        }
        c.d[c.len++] = a.d[i]-b.d[i];
    }
    while(c.len-1>=1&&c.d[c.len-1]==0){
        c.len--;
    }
    return c;
}
bign multi(bign a,int b){
    bign c;
    int flag = 0;
    for(int i=0;i<a.len;i++){
        int temp = a.d[i]*b+flag;
        c.d[c.len++] = temp%10; // 个位作为该位的结果
        flag = temp/10;// 高出的部分作为下一位的进位
    }
    // 如果进位不等于0,则表示进位不止一位
    while(flag!=0){
        c.d[c.len++] = flag %10;
        flag/=10;
    }
    return c;
}
bign divide(bign a,int b,int& r){
    bign c;
    c.len = a.len;
    for(int i=a.len;i>=0;i--){
        r = r*10 + a.d[i];
        if(r<b) c.d[i] = 0;
        else{
            c.d[i] = r/b;
            r = r%b;
        }
    }
    while(c.len-1>=1&&c.d[c.len-1]==0){
        c.len--;
    }
    return c;
}
void printbign(bign re){
    for(int i=re.len-1;i>=0;i--){
        printf("%d",re.d[i]);
    }
    return;
}
int main(){
    char str1[1000],str2[1000];
    scanf("%s%s",str1,str2);
    bign a= change(str1);
    bign b = change(str2);
    printbign(add(a,b));
    printf("\n");
    printbign(sub(a,b));
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值