从2开始试除是最直接的质因数分解方法:持续除尽每个找到的最小因子,循环至√n即可,剩余大于1的n本身即为最后一个质因子。

用 for 循环从 2 开始试除是最直接的方法
质因数分解本质就是不断找最小的能整除当前数的素数,所以从 2 开始逐个试除最直观。关键不是“快”,而是“稳”——它不依赖额外的素数表或预处理,适合单次、中小规模(比如 n ≤ 10^9)分解。
注意两点:一是每次找到一个因子后要持续除尽,比如 12 遇到 2 得除两次;二是循环只需到 sqrt(n),因为大于该值的因子最多只有一个(即剩余的 n 本身)。
常见错误是循环条件写成 i 或漏掉最后剩下的那个大质数:
void prime_factorize(int n) {
for (int i = 2; i * i <= n; i++) {
while (n % i == 0) {
printf("%d ", i);
n /= i;
}
}
if (n > 1) printf("%d", n); // 这行不能少
}
用 std::vector 存结果比打印更实用
实际项目里,你很少真把因子一个个 printf 出来。更多时候要参与后续计算(比如算约数个数、LCM/GCD),所以存进 std::vector<int></int> 是更自然的选择。
立即学习“C++免费学习笔记(深入)”;
参数设计上建议传入引用避免拷贝,同时注意类型:如果输入可能达 10^12,就得用 long long,否则 i * i 在 i ≈ 10^6 时就溢出了。
示例:
#include <vector>
std::vector<long long> factorize(long long n) {
std::vector<long long> res;
for (long long i = 2; i * i <= n; i++) {
while (n % i == 0) {
res.push_back(i);
n /= i;
}
}
if (n > 1) res.push_back(n);
return res;
}
i += 1 和 i += 2 的取舍要看输入范围
纯暴力试除用 i++ 简单可靠,但对偶数优化明显:除了 2,其余偶数都不可能是质因数。所以可以先单独处理 2,然后让 i 从 3 开始每次加 2。
但这只在 n 很大(比如接近 10^12)且调用频繁时才值得加——代码变长,可读性略降,而对 n 几乎没差别。
优化版要点:
- 先 while 处理所有因子 2
- 循环从
i = 3开始,条件仍是i * i - 循环内
i += 2,且仍需保留if (n > 1)收尾
遇到重复因子多的数(如幂次形式)性能会明显下降
比如分解 2^30,基础版本要做 30 次除法和判断;虽然总次数仍远小于 sqrt(n),但常数变大。此时可考虑先快速幂检测小质数的高次幂(例如用 while (n % 4 == 0) 批量除),但一般没必要——除非你明确知道输入分布极度偏斜。
真正容易被忽略的是:C++ 没有内置的“下一个质数”函数,别试图手写埃氏筛再查表来加速单次分解——筛到 sqrt(n) 的开销通常比直接试除还高,尤其当 n 不大时。
最稳妥的做法,就是老老实实从 2 开始试除,加上 i * i 和结尾判断这两处关键检查。


















