要快速判断一个数是否为质数,可以采用以下优化后的试除法,结合数学规律大幅减少计算量:
步骤说明
-
处理特殊情况:
- 若 ( n \leq 1 ),不是质数。
- 若 ( n = 2 ) 或 ( n = 3 ),是质数。
- 若 ( n ) 能被 2 或 3 整除,不是质数。
-
优化试除范围:
- 所有质数(除 2 和 3)都可表示为 ( 6k \pm 1 ) 的形式。
- 只需检查 ( 5 ) 到 ( \sqrt{n} ) 之间的 ( 6k \pm 1 ) 的数。
-
循环检查:
- 以 6 为步长,每次检查 ( i ) 和 ( i+2 ) 是否能整除 ( n )。
C++ 代码实现
#include <iostream>
#include <cmath>using namespace std;bool is_prime(int n) {if (n <= 1) return false; // 小于等于1的数不是质数if (n <= 3) return true; // 2和3是质数if (n % 2 == 0 || n % 3 == 0) // 排除能被2或3整除的数return false;// 检查形如6k±1的数,直到i超过sqrt(n)for (int i = 5; i * i <= n; i += 6) {if (n % i == 0 || n % (i + 2) == 0)return false;}return true;
}int main() {int num;cout << "输入一个整数: ";cin >> num;if (is_prime(num))cout << num << " 是质数" << endl;elsecout << num << " 不是质数" << endl;return 0;
}
复杂度分析
- 时间复杂度:( O(\sqrt{n}) ),但实际运行次数比普通试除法减少约 3 倍。
- 空间复杂度:( O(1) ),仅需常数空间。
优化原理
- 减少除数范围:通过数学推导,质数必定出现在 ( 6k \pm 1 ) 的序列中,避免检查不必要的数。
- 提前终止条件:当 ( i^2 > n ) 时停止循环,确保只检查到 ( \sqrt{n} )。
- 快速排除偶数:先处理 2 和 3 的倍数,直接跳过后续循环。
示例测试
- 输入:7 → 输出:是质数
- 输入:25 → 输出:不是质数(5×5)
- 输入:997 → 输出:是质数(大质数)
- 输入:1000001 → 输出:不是质数(101×9901)
这种方法结合数学规律和代码优化,能高效处理大多数情况下的质数判断需求。对于极大数(如加密用的大质数),可进一步使用概率性算法如 米勒-拉宾素性测试 进行更快速判断。