大整数加法【信息学奥赛一本通-1168】

1168:大整数加法

1168:大整数加法
【题目描述】
求两个不超过200位的非负整数的和。
【输入】
有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。
【输出】
一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
【输入样例】
22222222222222222222
33333333333333333333
【输出样例】
55555555555555555555

问题分析

  1. 为什么使用数组

    因为 int 的字节长度是4个字节,占32位,数值范围在 -32768~32767
    long long 的字节长度是8个字节,占64位,的数值范围 -2147483648~2147483647
    题目当中计算最高200位的数值运算使用 int 或 long long 已经不满足了
    所以我们采用数组,运用加法基本原理,逢十进一,来解决高精度加法计算问题
    我们以输入 123456789 + 5723169 为例

  2. 使用字符数组来接收
   char a[1000], b[1000];
   cin >> a >> b;
   或者
   char a[1000], b[1000];
   cin.getline(a, 1000);
   cin.getline(b, 1000);
字符数组 a
a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]...
123456789...
字符数组 b
b[0]b[1]b[2]b[3]b[4]b[5]b[6]...
5723169...
  1. 把字符数组转换成整型数组
   // 字符数组 a 转换  注意字符数组与整型数组数值存放的位置(颠倒)
   int la[1000];
   memset(la, 0, sizeof(la));         // 初始化 la 数组,使之都为0
   int lena = strlen(a);              // 求实际输入字符数组 a 的长度
   for (int i = 0; i < lena; i++) {
       la[i] = a[lena - 1 - i] - '0'; // 数字字符转换成整型数字的时候,需要减字符'0',或者减48,参考阿斯克码表
   }
   // 字符数组 b 转换  同字符数组 a 的转换
   int lb[1000];
   memset(lb, 0, sizeof(lb));
   int lenb = strlen(b);
   for (int i = 0; i < lenb; i++) {
       lb[i] = b[lenb - 1 - i] - '0';
   }
转换后的整型数组 la
la[0]la[1]la[2]la[3]la[4]la[5]la[6]la[7]la[8]...
987654321...
转换后的整型数组 lb
lb[0]lb[1]lb[2]lb[3]lb[4]lb[5]lb[6]...
9613275...
整型数组 lc
lc[0]lc[1]lc[2]lc[3]lc[4]lc[5]lc[6]lc[7]lc[8]...
...
  1. 运用加法原理进行计算(逢十进一)
    int lc[1010], lenc = 0;                // lc 表示计算的结果,lenc 表示结果有多少位
    memset(lc, 0, sizeof(lc));
    for (int i = 0; i < lena || i < lenb; i++) {
        lc[i + 1] = (la[i] + lb[i]) / 10;  // 进位
        lc[i] = (la[i] + lb[i]) % 10;      // 取个位
        lenc++;                            // 记录和的结果有多少位
    }
  1. 去掉最高位之前的零,输出整型数组 lc
    while (lc[lenc] == 0 && lenc >= 0) { 
        lenc--;             // 去掉最高位之前的零
   }
    for (int i = lenc; i >= 0; i--) {
        cout << lc[i];      // 注意数字在数组中保存的位置 
    }

参考代码

#include <bits/stdc++.h>

using namespace std;

int main() {

    char a[1000], b[1000];
    cin.getline(a, 1000);
    cin.getline(b, 1000);


    int la[1000], lb[1000], lc[1010], lenc = 0;
    memset(la, 0, sizeof(la));
    memset(lb, 0, sizeof(lb));
    memset(lc, 0, sizeof(lc));
    int lena = strlen(a),lenb = strlen(b);
    for (int i = 0; i < lena; i++) {
        la[i] = a[lena - 1 - i] - '0';
    }
    for (int i = 0; i < lenb; i++) {
        lb[i] = b[lenb - 1 - i] - '0';
    }
    for (int i = 0; i < lena || i < lenb; i++) {
        lc[i + 1] = (la[i] + lb[i] + lc[i]) / 10;
        lc[i] = (la[i] + lb[i] + lc[i]) % 10;
        lenc++;
    }
    while (lc[lenc] == 0 && lenc >= 0) {
        lenc--;
    }
    for (int i = lenc; i >= 0; i--) {
        cout << lc[i];
    }
    cout << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值