埃拉托色尼筛法介绍:
要得到自然数n以内的全部素数,必须把不大于
给出要筛数值的范围n,找出以内的素数。先用2去筛,即把2留下,把2的倍数剔除掉;再用下一个质数,也就是3筛,把3留下,把3的倍数剔除掉;接下去用下一个质数5筛,把5留下,把5的倍数剔除掉;不断重复下去......。
代码实现(埃式筛法):复杂度O(nloglogn)
const int N = 1000005;
int primes[N], book[N], cnt;
void check(int maxn){
for(int i = 2; i <= maxn; i++){
if(!book[i]){
primes[cnt++] = i; //没被筛掉,那就加到素数表中
for(int j = i * 2; j <= maxn; j += i) book[j] = 1; //筛掉i的倍数
}
}
//输出1-maxn的所有素数
for(int i = 0; i < cnt; i++)
printf("%d ", primes[i]);
}
欧拉筛法(复杂度O(n)):
主要防止一个数被多次筛掉,比如12,被2,3都筛了一次。而欧拉筛法就是只让最小的质因子筛(12的话就只让2筛)
int book[N], prime[N], cnt; //book[i] = 1表示被划去了,book[i] = 0表示是素数,cnt是素数表的大小
void euler(int n) {
for (int i = 2; i <= n; i++) {
if (!book[i]) prime[cnt++] = i;
for (int j = 0; j < cnt; j++) { //在已有的素数表中寻找i的质因子
if (i * prime[j] > n) break; //减少不必要的运算
book[i * prime[j]] = 1;
if (i % prime[j] == 0) break; //存在其质因子说明i是一个合数,就break
}
}
}