欧拉素数筛选

给定一个正整数n,找到其范围内的所有素数,并利用最小的时间复杂度

这道题在面试的时候,面试官给了一个小时且不断提示都没能做到完美。。。

用了欧拉筛选这个数学方法,主要有两点 1.标记出非素数 2.标记的过程中 只判断必要的

#include<cstdio>
#include<cstring>
const int maxn=10000;

int prime[maxn+1];
void getprime() {
    memset(prime,0,sizeof(prime));
    for(int i=2;i<=maxn;i++) {
        if(!prime[i]) prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++) {
            prime[i*prime[j]]=1;
//下面这一步是比较难理解的
            if(i%prime[j]==0) break;
        }
    }
}

int main() {
    getprime();
    for(int i=1;i<=prime[0];i++) {
        printf("%d\n",prime[i]);
    }
}

prime[n]充当最小素因子,一旦被整除就break,后面没有筛除的,说明i不是他们的最大因数。这样就不会重复了。

举个例子  i为4 prime[j] 为2 ,4*2已经算出8了,4%2为0,根据数学理论证明(我没搞太懂),4不是后面数的最大因子了

(比如6*2为12,这个6就大于4),下面的就该交给别的比较大的数去筛选了

 

另一种写法更易于理解

void getPrime(int n) {
    for (int i = 0; i <= n; ++i)
        pri[i] = i;
    pri[1] = 0;
    for (int i = 2; i <= n; ++i) {
        if (!pri[i]) continue;//  ==0说明不是质数 已经处理过了
        pri[++pri[0]] = i;
        for (int j = 2; i * j <= n && j < n; ++j) {
            pri[i * j] = 0;
        }
    }
}

 

posted @ 2020-03-08 19:30  大老虎打老虎  阅读(302)  评论(0)    收藏  举报