问题描述:求N以内的所有素数(素数:只能被1和它本身整除)
1 常规筛
#include<iostream>
using namespace std;
int main(){
int n,flag;
cin>>n;
for(int j=2;j<=n;j++){ //首先保证从2-N的所有数遍历一遍
flag=1; //这里还有一个要点就是有一个标杆记录是否为素数
for(int i=2;i*i<=j;i++){ //在找每个数的因数时,一般是到 j/2,但更聪明的方法是到这个数的根,有数学家证明,一个数的因数平均对称分布在它的正平方根两边。
if(j%i==0){
flag=0;
break;
}
}
if(flag==1)cout<<j<<endl;
}
return 0;
}
2 埃式筛
思路:首先2是最小的素数,在规定的范围内,先把2的所有倍数去掉,在剩下的所有数中,最小的数为3,3也为素数,再把3的所有倍数去掉,剩下的大于3的数中最小的是5,所以5也是素数,再把5的所有倍数去掉,以此类推。
复杂度为o(nlogn)
#include<iostream>
#include<math.h>
using namespace std;
int main(){
long long max=200000;//可计算的最大值
long long a[max],i,j;10
long long n;
cin>>n;
a[0]=0;
for(i=1;i<=n;i++){
a[i]=i;//赋值
}a[1]=0;
for(i=2;i<=n;i++){
if(a[i]==0)continue;//如果不是质数,直接进入下一次循环
cout<<i<<endl;//输出质数
for(j=i;i*j<=n&&j<n;++j)a[i*j]=0; //2的倍数,3的倍数都赋值为0
}
}
执行结果和上述截图相同。
3 欧拉筛
通过将合数分解为质数,根据质数判断当前合数是否被标记过
#include<iostream>
using namespace std;
const int maxn=10000;
int prime[maxn],pNum=0;
bool p[maxn]={false};
void eulerSieve(int n){
for(int i=2;i<=n;i++){
if(p[i]==false)prime[pNum++]=i;
for(int j=0;j<pNum;j++){
if(i*prime[j]>n)break;
p[i*prime[j]]=true;
if(i%prime[j]==0)break;
}
}
}
int main(){
int n,i;
cin>>n;
eulerSieve(n);
for(i=0;i<pNum;i++){
cout<<prime[i]<<endl;
}
return 0;
}
这个太难了......