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

七、总结

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

相关推荐
我材不敲代码1 天前
Python实现打包贪吃蛇游戏
开发语言·python·游戏
身如柳絮随风扬1 天前
Java中的CAS机制详解
java·开发语言
-dzk-1 天前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
韩立学长1 天前
【开题答辩实录分享】以《基于Python的大学超市仓储信息管理系统的设计与实现》为例进行选题答辩实录分享
开发语言·python
froginwe111 天前
Scala 循环
开发语言
m0_706653231 天前
C++编译期数组操作
开发语言·c++·算法
故事和你911 天前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
Bruk.Liu1 天前
(LangChain实战2):LangChain消息(message)的使用
开发语言·langchain
qq_423233901 天前
C++与Python混合编程实战
开发语言·c++·算法
m0_715575341 天前
分布式任务调度系统
开发语言·c++·算法