目录
- 质数(素数)
- 合数
- 指数
- 整数唯一分解定理
- 素数筛选——试除法
- 素数筛选——试除法开平方优化
- 素数筛选——埃拉托斯特尼筛法
1. 质数(素数)
定义:大于1的自然数,除了1和它本身外没有其他因数
特性:最小的质数是2,唯一偶质数
示例代码:判断质数
bool isPrime(int n) {
if (n <= 1) return false;
for (int i = 2; i < n; i++) {
if (n % i == 0) return false;
}
return true;
}
// 测试示例
int main() {
cout << "7是质数吗?" << isPrime(7); // 输出1(true)
cout << "\n9是质数吗?" << isPrime(9); // 输出0(false)
}
2. 合数
定义:大于1的自然数,除了1和它本身还有其他因数
特性:最小合数是4,所有大于2的偶数都是合数
示例代码:判断合数
bool isComposite(int n) {
return (n > 1) && !isPrime(n);
}
3. 指数
定义:表示相同因数相乘的次数
应用:质因数分解中记录质数的幂次
示例:12 = 2²×3¹
指数分别为2和1
4. 整数唯一分解定理
定理:每个大于1的整数都可以唯一表示为质数的乘积
示例代码:质因数分解
void primeFactorization(int n) {
for (int i = 2; i <= n; i++) {
int exponent = 0;
while (n % i == 0) {
exponent++;
n /= i;
}
if (exponent > 0) {
cout << i << "^" << exponent << " ";
}
}
}
// 测试示例
int main() {
primeFactorization(60); // 输出2^2 3^1 5^1
}
5. 素数筛选——试除法
原理:对每个数进行质数判断
示例代码
void trialDivision(int n) {
for (int i = 2; i <= n; i++) {
if (isPrime(i)) {
cout << i << " ";
}
}
}
// 测试示例
int main() {
trialDivision(20); // 输出2 3 5 7 11 13 17 19
}
6. 试除法开平方优化
优化原理:只需检查到√n即可,因为整数n是合数,必存在一对因数满足 1 < a ≤ b < n,使得 a×b = n,所以只需要取√n即可
优化代码
bool isPrimeOptimized(int n) {
if (n <= 1) return false;
for (int i = 2; i*i <= n; i++) { // 关键优化点
if (n % i == 0) return false;
}
return true;
}
7. 埃拉托斯特尼筛法
算法步骤:
- 创建1~n的标记数组,全部标记为true
- 从最小质数开始划去所有倍数
- 剩余未划去的数即为质数
埃拉托斯特尼筛法图解
示例代码
void sieveOfEratosthenes(int n) {
vector<bool> isPrime(n + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i <= n; i++) {
if (isPrime[i]) {
for (int j = 2 * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
for (int i = 2; i <= n; i++) {
if (isPrime[i]) cout << i << " ";
}
}
// 测试示例
int main() {
sieveOfEratosthenes(30);
// 输出2 3 5 7 11 13 17 19 23 29
}
算法复杂度对比
方法 | 时间复杂度 | 适用场景 |
---|---|---|
普通试除法 | O(n²) | 小范围判断 |
开平方优化试除法 | O(n√n) | 中等范围判断 |
埃拉托斯特尼筛法 | O(n loglogn) | 大规模筛选 |