[洛谷P1601]高精度加法的C++解决办法

高精度加法的C++解决办法

题目描述:

对于输入的两个不超过100位数的非负整数,给出两数之和。

输入格式:

在两行中分别给出两个不超过100位数字的非负整数。

输出格式:

在一行中输出两数之和。

输入样例:

123
12

输出样例

135

题目解读:

难点:

相比于常规的A+Bproblem,此题非常规的点是这两个给定的A,B是不超过100位数字的非负整数,两个数据大小都超过了C及C++中的所有数据类型,作为不具备高精度加法的编程语言,我们就无法简单以A+B去解决这个问题。

解题思路:

在这里插入图片描述

利用小学二年级知识,我们可以逐位逐位相加,满十进一。由此,解题思路应运而生。

算法描述

  1. 利用两个字符数组接受输入的数字字符。
  2. 将字符串数组转换为整型数组并倒转数组。
  3. 逐位相加,并使用一个数组存储各位相加的数字。遵循满十进一规则。
  4. 输出结果。

代码实现

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    char A[100] = { '\0' }, B[100] = { '\0' };
    cin >> A;
    cin >> B;
    //分别计算字符数组A,B的长度a,b并记录一个较大值c
    int a1 = strlen(A);
    int b1 = strlen(B);
    int c1 = a1 >= b1 ? a1 : b1;
    int a[100] = { 0 }, b[100] = { 0 };
    for (int i = 0; i < a1; i++)
    {
        a[i] = A[a1 - 1 - i] - 48;//实现字符向数字转换 并倒转整个数组
    }
    for (int i = 0; i < b1; i++)
    {
        b[i] = B[b1 - 1 - i] - 48;
    }
    int sum[101] = { 0 };//为什么sum的数组要多开一个长度呢?
    for (int i = 0; i < 100; i++)
    {
        int item = a[i] + b[i];
        sum[i] += item % 10;//对十取余,正常获取每位数字(即便它不需要进位)
        sum[i + 1] = item / 10;//若满十则进一
    }
    if (sum[c1] != 0)//当在最高位进一时,若sum定义仍为一百的长度,可能会造成溢出,无法存储进位。
    {
        cout << sum[c1];
    }
    for (int i = c1 - 1; i >= 0; i--)//从高位到低位依序输出
    {
        cout << sum[i];
    }
    return 0;
}

问题:为什么统计sum时一个使用+=一个使用=?

 for (int i = 0; i < 100; i++)
    {
        int item = a[i] + b[i];
        sum[i] += item % 10;//对十取余,正常获取每位数字(即便它不需要进位)
        sum[i + 1] = item / 10;//若满十则进一
    }

因为,进位时,下一位永远是0(数组已全部初始化置0),我们可以简单地给它赋值为1,实现的操作与+=1相同;

然而,在计算当前位数时,有可能在计算上一位数时完成了进位操作,直接赋值就将上一次的进位1抵消掉了。

原题链接

https://www.luogu.com.cn/problem/P1601

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值