C++ 大数乘法

C++ 高精度整数乘法实现(大数乘法逐位模拟)

摘要

在 C++ 中,当两个整数的位数超过内置整型范围时(如 long long 也只能表示约 19 位数字),我们需要使用字符串或数组来模拟大数的运算。本文将讲解如何实现大整数乘法,通过逐位模拟手工竖式乘法来实现任意长度整数的乘法计算,并给出可直接运行的示例代码和详细解析。


一、问题描述

给定两个非负整数 ab(以字符串形式表示),要求计算它们的乘积并返回字符串形式的结果。

例如:

复制代码
输入: a = "12345", b = "678"
输出: "8369910"

注意 :如果任意一个输入为 "0",输出必须为 "0"


二、算法思想

高精度整数乘法主要模拟我们手工计算的竖式乘法:

  1. 逐位相乘

    • 外层循环从第二个数(b)的最低位到最高位遍历。
    • 内层循环从第一个数(a)的最低位到最高位遍历。
    • 将当前位的乘积加上上一次的进位以及结果数组当前位置已有的值。
  2. 进位处理

    • 每一位乘法的结果可能大于 10,需要向高位进位。
    • 每轮外层循环结束后,如果还有进位,需要写入数组高位。
  3. 移位加法

    • 外层循环每进行一轮,就相当于乘 b 的当前位对 a 的整个乘积,然后按位数移动(类似手算竖式,乘 b 的个位不移,十位向左移一位,百位移两位)。
  4. 最终结果

    • 通过整型数组保存每一位的结果,最后转换为字符串。
    • 去掉前导零。

三、代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>

typedef long long ll;

// 将数组转为字符串,并去掉前导零
std::string num_arr_to_string(std::vector<int> arr){
    std::string result("");
    bool begin = false;
    for (int c: arr){
        if (c != 0) begin = true;
        if (begin) result += std::to_string(c);
    }
    return result.empty() ? "0" : result; // 注意处理全零的情况
}

// 判断字符串是否全为零
bool is_zero_str(const std::string &a){
    for (char c: a) if (c != '0') return false;
    return true;
}

// 大整数乘法
std::string big_num_multi(const std::string &a, const std::string &b){
    if (is_zero_str(a) || is_zero_str(b)) return "0";

    int n = a.size();
    int m = b.size();
    int max_len = n + m; // 最多 n+m 位
    std::vector<int> arr(max_len, 0);

    for (int i = m - 1; i >= 0; i--){ // b 的每一位
        int jin = 0; // 每轮外层循环的进位
        int idx = max_len - (m - i); // 当前外层位对应数组的索引
        for (int j = n - 1; j >= 0; j--){ // a 的每一位
            int b_num = b[i] - '0';
            int a_num = a[j] - '0';
            int multi_num = b_num * a_num + jin + arr[idx]; // 乘积 + 进位 + 数组已有值
            arr[idx] = multi_num % 10;
            jin = multi_num / 10;
            idx--;
        }
        if (jin) arr[idx] = jin; // 外层循环结束后剩余进位
    }

    return num_arr_to_string(arr);
}

int main(){
    std::string a, b;
    std::cin >> a >> b;
    std::cout << big_num_multi(a,b) << std::endl;
    return 0;
}

四、关键点解析

  1. 数组长度

    • 乘法结果的最大长度为 n + m 位。
    • 使用整型数组保存每一位,最后转字符串返回。
  2. 进位管理

    • 每一位乘法结果大于等于 10 时,需要向高位进位。
    • 注意 :每轮外层循环结束后,必须将 jin 重置为 0,否则会影响下一轮计算。
  3. 移位处理

    • 外层循环控制 b 的位数,乘完一轮后结果数组需要对应移位。
    • idx = max_len - (m - i) 计算每轮加法的起始位置。
  4. 零处理

    • 如果任意输入是 "0",结果直接返回 "0",避免多余计算。
    • 转字符串时去掉前导零,保证输出美观。

五、时间与空间复杂度

  • 时间复杂度O(n * m),n、m 分别为两个数的长度,每一位都需要乘一次。
  • 空间复杂度O(n + m),数组保存乘积每一位的结果。

六、示例

输入:

复制代码
123 456

输出:

复制代码
56088

输入:

复制代码
999 999

输出:

复制代码
998001

输入:

复制代码
0 123456

输出:

复制代码
0

七、总结

  • 大整数乘法可以通过模拟手工竖式乘法实现。
  • 核心思想是逐位相乘 + 进位管理 + 移位累加
  • 适用于任意长度的非负整数字符串乘法。

相关推荐
listhi5202 小时前
基于空时阵列最佳旋转角度的卫星导航抗干扰信号处理的完整MATLAB仿真
开发语言·matlab·信号处理
lly2024063 小时前
Kotlin 类和对象
开发语言
是苏浙3 小时前
零基础入门C语言之C语言内存函数
c语言·开发语言
zhmhbest3 小时前
Qt 全球峰会 2025:中国站速递 —— 技术中立,拥抱更大生态
开发语言·qt·系统架构
程序员大雄学编程3 小时前
用Python来学微积分30-微分方程初步
开发语言·python·线性代数·数学·微积分
关于不上作者榜就原神启动那件事3 小时前
模拟算法乒乓球
开发语言·c++·算法
初圣魔门首席弟子3 小时前
C++ STL list 容器学习笔记:双向链表的 “小火车“ 操控指南
c++·windows·笔记·学习
Madison-No73 小时前
【C++】关于list的使用&&底层实现
数据结构·c++·stl·list·模拟实现
88号技师3 小时前
2025年7月一区SCI优化算法-Logistic-Gauss Circle optimizer-附Matlab免费代码
开发语言·算法·数学建模·matlab·优化算法