「C++小例子」123456789+1=?【004】

海轰Pro

共 5307字,需浏览 11分钟

 ·

2021-05-01 22:40

1题目

用户依次输入两个正数  a、b

计算:a+b=?

2解答

看到题目

求a+b

简单

return a+b!

#include <iostream>
using namespace std;

int main()
{
    int a;
    int b;
    cout<<"输入第一个数:";
    cin>>a;
    cout<<"输入第二个数:";
    cin>>b;
    int ans=a+b;
    cout<<"a+b="<<ans<<endl;
    return 0;
}

测试:2+3(通过)

测试:1111111111+1111111111(失败)

失败原因:

  • a、b都为int类型,a+b结果可能会造成溢出(超过int所能表示数的最大范围)

这时可能会想到

不用int类型,使用范围更大的long或者long long呢 ?

其实也是一样的

无论是long还是long long

都会有最大数,不小心都会产生溢出

比如计算:11111111111111111111123122222222222222222222222222222222222233333333333342343243243243242343+1

参考解答 - 1

思路:模拟

这里我们使用string类型存储数a、数b

假设a='123' , b='12'

使用小学加法计算:

  1 2 3
+   1 2
---------
  1 3 5

假设a='123456789' , b='11'

  1 2 3 4 5 6 7 8 9
+               1 1
---------------------
  1 2 3 4 5 6 8 0 0

依次类推

我们发现

当进行两个数相加时

  • 每次进行的步骤就是对应的数相加
  • 如果有进位,还需要加上进位
  • 最后我们只需要得到和的个位数以及产生的进位

简单的说

每次进行的步骤就是

p+q+count

注:

  • count表示进位
  • p、q表示竖式中对应的元素

结合上述思路

得到以下代码:

#include <iostream>
using namespace std;


int main()
{
    string a;
    string b;
    string ans;
    cout<<"输入第一个数:";
    cin>>a;
    cout<<"输入第二个数:";
    cin>>b;
    int count=0;
    int i=a.length()-1;//a的长度-1
    int j=b.length()-1;//b的长度-1
    
    // 对应数相加 
    while(i>=0 && j>=0) {
        ans += ((a[i]-'0'+b[j]-'0'+count)%10+'0');
        count = (a[i]-'0'+b[j]-'0'+count)/10;
        --i;
        --j;
    }
    // 若a还未遍历完
    while(i>=0) {
        ans += ((a[i]-'0'+count)%10+'0');
        count = (a[i]-'0'+count)/10;
        --i;
    }
    
    // 若b还未遍历完
    while (j>=0)
    {
        ans += ((b[j]-'0'+count)%10+'0');
        count = (b[j]-'0'+count)/10;
        --j;
    }
    
    // 补1 (重要)
    if(count>0) {
        ans += '1';
    }
    
    //翻转
    reverse(ans.begin(),ans.end());
    
    cout<<"a+b="<<ans<<endl;
    return 0;
}

运行结果

测试:1+9(通过)

测试:11111111111111111111+1111111111(通过)

疑问1

为什么最后需要进行reverse()?

假设a='123' , b='1'

我们首先运算的是 3+1

再将其添加至ans

再算2+0

再算1+0

得到ans=421

而正确答案是:124

所以需要翻转

疑问2

为什么最后需要进行补1?

假设a='9' , b='1'

如果只是按照对应位置数相加

那么答案就是:0

因为同时遍历完了a与b

但是最后还产生进位1

还需要进行一次运算

正确答案应该是:10

所以

如果a、b都遍历完后,进位不为0,那么还需要进行补1的操作

简化代码

#include <iostream>
using namespace std;


int main()
{
    string a;
    string b;
    string ans;
    cout<<"输入第一个数:";
    cin>>a;
    cout<<"输入第二个数:";
    cin>>b;
    int count=0;
    int i=a.length()-1;//a的长度-1
    int j=b.length()-1;//b的长度-1
 
    while(i>=0 || j>=0 || count!=0) {
        int x= i>=0? a[i]-'0':0;
        int y= j>=0? b[j]-'0':0;
        ans += ((x+y+count)%10+'0');
        count = (x+y+count)/10;
        --i;
        --j;
    }   
 
    //翻转
    reverse(ans.begin(),ans.end());
    
    cout<<"a+b="<<ans<<endl;
    return 0;
}

运行环境

Visual Studio Code

3结语

欢迎小伙伴们提供其余的解法

这里海轰提供的代码仅供参考,希望对您有所帮助,如有错误欢迎小伙伴指正~

我是海轰ଘ(੭ˊᵕˋ)੭,如果您觉得写得可以的话,请点个赞吧

谢谢支持❤️

写留言|查看留言

浏览 26
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报