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

本文详细解析了如何使用字符数组实现大整数加法,涉及字符数组转整型数组、加法原理及进位操作,适用于超过32位整数的计算,重点展示了逢十进一的算法步骤和结果处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
### 信息学奥赛一本 - 大整数加法信息学竞赛中,大整数运算是一个常见的题目类型。由于计算机内置的数据类型(如 `int`、`long long` 等)有范围限制,当数字超过这个范围时,就需要使用特殊的方式来处理大整数。 #### 大整数加法的基本思路: 1. **字符串表示**: 因为普数据类型无法存储非常大的数字,所以常我们会将大整数用字符串的形式输入,并逐位进行计算。 2. **逆序存取**: 将两个大整数从低位到高位依次相加,可以方便地处理进位问题。因此,我们常常会先对字符串进行反转,然后按位相加。 3. **逐位相加并处理进位**: 对每一位进行相加操作,如果某一位的结果大于等于10,则需要向更高的一位进位。最后再检查最高位是否有进位。 4. **结果输出**: 计算完成后,记得去掉前导零并将结果再次反转回来。 下面给出一个简单的 C++ 示例代码来演示如何实现大整数加法: ```cpp #include <iostream> #include <string> using namespace std; // 实现大整数加法函数 string addBigNumbers(const string& num1, const string& num2) { int len1 = num1.size(); int len2 = num2.size(); // 补齐长度较短的数字前面补零 if (len1 > len2) { num2.insert(0, len1 - len2, '0'); } else { num1.insert(0, len2 - len1, '0'); } int maxLength = max(len1, len2); string result; int carry = 0; // 进位标志 for (int i = maxLength - 1; i >= 0; --i) { int sum = (num1[i] - '0') + (num2[i] - '0') + carry; carry = sum / 10; result.push_back(sum % 10 + '0'); // 只保留当前位数值 } if (carry != 0) result.push_back(carry + '0'); // 最后的进位别忘了加上去哦! reverse(result.begin(), result.end()); // 结果翻转回正常顺序 return result; } int main() { string a, b; cin >> a >> b; cout << "两数之和:" << addBigNumbers(a, b) << endl; return 0; } ``` 过以上步骤就可以完成基本的大整数加法了。当然,在实际比赛中可能会遇到更复杂的情况,比如负数等情况,这都需要额外考虑进去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值