一、埃拉托斯特尼(Eratosthenes)筛法
时间复杂度O(n logn)
#include<stdio.h> #define maxn 100000 bool valid[maxn]; void getprime(int N,int &tot,int ans[]){ tot=0; int i,j; for(i=2;i<=N;++i) valid[i]=true; for(i=2;i<=N;++i) if(valid[i]){ if(N/i<i) break; for(j=i*i;j<=N;j+=i) valid[j]=false; } for(i=2;i<=N;++i) if(valid[i]) ans[tot++]=i; } int main(){ int n,N=1000; //n为素数数量 ,N为1000以内的素数 int prime[maxn]; //存储素数值 getprime(N,n,prime); for(int i=0;i<n;i++) printf("%d,",prime[i]); }
二、欧拉(Euler)筛法----线性筛 O(n)
#include<stdio.h> #include<string.h> #define ms(x,v) memset(x,v,sizeof(x)) const int MAX=10000; int prime[MAX+10]; //记录素数值 int notprime[MAX+10]; //记录每个下标是否是合数,0不是合数1是合数 int Euler_Prime(int N){ ms(prime,0); ms(notprime,0); int n=0; int i; for(i=2;i<=MAX;i++) { //如果是素数则记录 if(!notprime[i]) prime[n++]=i; for(int j=0;j<n;j++) { if(i*prime[j]>N) //超过约定的最大数就不考虑了,会由后面的数来筛选,这样就能成线性筛选,使时间复杂度为O(n) break; notprime[i*prime[j]]=1; //比如 i=6时,已存素数2,3,5;则得到 12,18,30为合数 if(i%prime[j]==0) //超过p1的就不考虑了,因为在后面会筛 break; //i=4时,只确认了8是合数,而接下来的3*4=12会由6*2来完成,因为否则将会发生重复查询,该算法本就是利用最小质因子来排除合数, //如果发现i能整除某一质因子prime[j],那就跳过,让后面的数来实现i*prime[j]的合数确定 } } return n; } int main(){ int N=1000;//求1000以内的素数 int n=Euler_Prime(N) ; for(int i;i<n;i++) printf("%d ",prime[i]); }