素数的线性筛选法
素数的线性筛法也被称为埃拉托斯特尼筛法(Eratosthenes Sieve)。
素数的线性筛法是一种高效地筛选出一定范围内所有素数的算法。其基本思想是从小到大遍历每个数,对于每个数,将其所有的倍数标记为合数,剩下的即为素数。
具体步骤如下:
初始化一个大小为n+1的bool数组is_prime,所有元素初始化为true,表示都是素数。
从2开始遍历到sqrt(n):
如果当前数字i是素数(即is_prime[i]为true),则将其所有的倍数标记为合数。即,从i*i开始,每隔i标记一个合数,直到大于n为止。
遍历完所有数字后,剩下的为素数。
这种方法的关键在于每个合数都被它的最小质因数筛掉,而且每个合数只会被筛选一次,因此效率很高。时间复杂度为O(nloglogn),空间复杂度为O(n)。
【参考程序】
#include <iostream>
#include <vector>
using namespace std;
vector<int> linearSieve(int n) {
vector<int> primes; // 存放素数
vector<int> is_prime(n + 1, true); // 标记是否为素数,默认全为true
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i); // 当前数是素数,加入素数数组
}
// 将当前素数的所有倍数标记为合数
for (int j = 0; j < primes.size() && i * primes[j] <= n; ++j) {
is_prime[i * primes[j]] = false;
if (i % primes[j] == 0) { // 跳出内层循环
break;
}
}
}
return primes;
}
int main() {
int n;
cout << "Enter the range (n): ";
cin >> n;
vector<int> primes = linearSieve(n);
cout << "Prime numbers up to " << n << " are:" << endl;
for (int prime : primes) {
cout << prime << " ";
}
cout << endl;
return 0;
}