long long 无法做大整数乘法因溢出(如10⁹×10⁹>10¹⁸),C++无内置高精度类型,需用vector倒序存数模拟竖式乘法:逐位相乘累加到res[i+j],再统一进位,最后去前导零。

为什么不能直接用 long long 做大整数乘法
因为 long long 最多存约 10¹⁸,两个 10⁹ 级的数相乘就溢出;更别说几百位的大整数。C++ 标准库不提供内置高精度整数类型,必须自己模拟手算过程——按位存储、进位处理、逐位相乘再累加。
vector<int></int> 存储 + 模拟竖式乘法是最实用的起点
把数字倒序存进 vector<int></int>(个位在 index 0),避免每次插入头部开销大。乘法本质是两层循环:外层遍历被乘数每一位,内层遍历乘数每一位,结果累加到 res[i + j] 位置,再统一处理进位。
- 输入字符串转为倒序
vector:比如"123"→{3,2,1} - 结果数组长度最多为
a.size() + b.size(),提前分配好空间 - 每轮
res[i + j] += a[i] * b[j],之后再单独做一次进位遍历(不要边乘边进位,容易错) - 最后去掉高位多余的
0,但至少保留一位(防止结果为"0")
// 示例核心逻辑片段
vector<int> mul(const vector<int>& a, const vector<int>& b) {
vector<int> res(a.size() + b.size(), 0);
for (int i = 0; i < a.size(); i++)
for (int j = 0; j < b.size(); j++)
res[i + j] += a[i] * b[j];
int carry = 0;
for (int i = 0; i < res.size(); i++) {
res[i] += carry;
carry = res[i] / 10;
res[i] %= 10;
}
while (res.size() > 1 && res.back() == 0) res.pop_back();
return res;
}
遇到前导零、负号、空输入怎么办
实际使用中,输入常带符号或无效字符。别依赖 stoi 或 stoll,它们会直接炸掉或截断。必须手动清洗:
- 先检查空字符串或全空白,直接返回
"0" - 记录开头是否有
'-',然后跳过;末尾再决定是否加负号 - 过滤非数字字符(比如空格、逗号),但要警惕
"-000"这种——应归一化为"0" - 如果清洗后只剩
"0"或空,直接返回"0",避免后续构造空vector导致越界
性能差?试试 Karatsuba 优化(仅当位数 > 1000)
朴素 O(n²) 在几千位时已明显卡顿。Karatsuba 是分治法,理论复杂度 O(n^log₂3) ≈ O(n^1.58),但常数大、对小数反而更慢。只在确定输入普遍超千位时才值得引入。
立即学习“C++免费学习笔记(深入)”;
- 必须递归实现,注意基线条件:比如
len 就切回朴素乘法 - 要补零使两数等长且为 2 的幂,否则分治边界易出错
- C++ 中递归深度和临时对象拷贝开销明显,建议用索引传参 + 原地操作,避免频繁
vector复制 - 别忘了处理符号:只在最外层判断一次正负,中间全用绝对值运算
真正难的不是写对算法,而是边界——比如 "0" * "123"、"-0000"、超长全 9 相乘后的进位链。这些地方不加测试,上线后第一例异常输入就会崩。


















