算法大师1:高精度加法——大数相加的奥秘-编程学习交流讨论版论坛-综合讨论-ZDZL
AI 文章摘要
高精度加法通过用数组逐位存储大数,解决内置整数类型范围不足的问题。核心做法是:将数字字符串倒序存入数组(个位在下标0),从低位到高位逐位相加并处理进位,循环条件需包含最高位可能的进位(`carry`),最终倒序输出结果。该方法本质模拟竖式计算,时间复杂度为O(max(n,m)),代码实现简洁,适用于任意长度的整数相加。

算法大师1:高精度加法——大数相加的奥秘

 

1. 问题引入

先看这道题:计算1234567890123456789+9876543210987654321=?
直接用int或long long行吗?
不行。

  • int:约2.1×10⁹,远远不够

  • long long:约9.2×10¹⁸,我给的数有19位,超了
    C++没有内置的”超大整数”类型。我们需要自己造一个。
    这就是高精度加法要解决的问题:用数组模拟数字的每一位,实现超大整数的加法运算。

2. 核心思想

高精度加法的核心思想只有一句话:
用数组存储数字的每一位,按位相加,处理进位。
就像小学列竖式一样:
   1 2 3 4

+ 5 6 7 8


   6 9 1 2
从个位开始加,满10进1。

3. 怎么存数字?

大数怎么放进数组?
比如123456789:

  • 正着存(下标0存最高位):[1,2,3,4,5,6,7,8,9]

  • 反着存(下标0存个位):[9,8,7,6,5,4,3,2,1]
    我选反着存。
    因为相加从个位开始,进位往高位传递。反着存让个位在数组开头,方便逐位处理,而且最高位在数组末尾,不用担心最高位进位导致数组越界。

    string s="123456789";
    vector<int> a;
    for(int i=s.size()-1;i>=0;i--){
    a.push_back(s[i]-'0');
    }
    //a=[9,8,7,6,5,4,3,2,1]
    //表示123456789

4. 高精度加法步骤

把两个用数组表示的大数a和b相加:

  1. 从第0位(个位)开始,逐位相加

  2. 加上来自低位的进位

  3. 如果结果≥10,保留个位,进位1

  4. 否则进位0

  5. 处理完所有位后,如果还有进位,在最高位补1

5. 代码实现

#include<bits/stdc++.h>
using namespace std;
vector<int>add(vector<int> a,vector<int> b) {
    vector<int> c;
    int carry=0,i=0;
    while(i<a.size()||i<b.size()||carry){
        int sum=carry;
        if(i<a.size()) sum+=a[i];
        if(i<b.size()) sum+=b[i];
        c.push_back(sum%10);
        carry=sum/10;
        i++;
    }
    return c;
}
int main() {
    string s1,s2;
    cin>>s1>>s2;
    vector<int> a,b;
    for(int i=s1.size()-1;i>=0;i--) a.push_back(s1[i]-'0');
    for(int i=s2.size()-1;i>=0;i--) b.push_back(s2[i]-'0');
    vector<int> c=add(a,b);
    for(int i=c.size()-1;i>=0;i--){
        cout<<c[i];
    }
    return 0;
}

输入:
1234567890123456789
9876543210987654321
输出:
11111111101111111110

6. 图解示例

计算[9,8,7](789)+[6,5,4](456):
步骤0:a=9,b=6,进位0,和15,当前位5,新进位1
步骤1:a=8,b=5,进位1,和14,当前位4,新进位1
步骤2:a=7,b=4,进位1,和12,当前位2,新进位1
步骤3:a无,b无,进位1,和1,当前位1,新进位0
结果:[5,4,2,1]反着读→1245

7. 注意点

  • 字符串怎么转数组:从末尾往前遍历,s[i]-‘0’

  • 为什么要反着存:方便按位相加和进位传递

  • 最高位进位怎么处理:循环条件加上||carry

  • 怎么输出结果:从数组末尾往前输出

8. 完整代码(简化版)

#include<bits/stdc++.h>
using namespace std;
int main() {
    string s1,s2;
    cin>>s1>>s2;
    int a[1000]={0},b[1000]={0},len1=s1.size(),len2=s2.size();
    for(int i=0;i<len1;i++) a[i]=s1[len1-1-i]-'0';
    for(int i=0;i<len2;i++) b[i]=s2[len2-1-i]-'0';
    int len=max(len1,len2),carry=0;
    for(int i=0;i<len;i++){
        int sum=a[i]+b[i]+carry;
        a[i]=sum%10;
        carry=sum/10;
    }
    if(carry) a[len++]=carry;
    for(int i=len-1;i>=0;i--) cout<<a[i];
    return 0;
}

9. 总结

  • 高精度加法是什么:用数组模拟超大整数的加法运算

  • 怎么存数字:反着存,下标0是个位

  • 加法核心:按位相加,处理进位

  • 循环条件:加上||carry处理最高位进位

  • 时间复杂度:O(max(n,m))

下一篇预告:算法大师2:高精度减法——解决大数相减