质数筛选一般用两种方法,埃氏筛法和欧拉筛法(线性筛)
埃氏筛法便于理解但是运行时间较长
欧拉筛法是埃氏筛法的升级版本
埃氏筛法
埃氏筛法是将素数的倍数排除,从而留下素数
因为素数只被 1 和本身整除,所以不会被排除
例如从2开始,4、6、8、…被排除
再从3开始,6、9、12、…被排除
因为4被排除,再从5开始
以此类推直到 n
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000010;
bool a[N];
int main()
{
int i,j,n,m,num;
scanf("%d",&n);
a[0]=a[1]=1;
num=0;
for(i=0;i<=n;i++)
{
if(a[i]) continue;//合数直接跳过
num++;
for(j=i;j<=n;j+=i)
{
a[j]=1;//将i的倍数全部排除
}
}
printf("%d\n",num);
}
但重复判断次数过多,例如12,要被2、4、6判断,因此花费时间较长
欧拉筛法(线性筛)
思路和埃氏筛法类似
但是将质数存入数组,筛选时用数组中质数判断,减少了判断次数
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000010;
int st[N],primes[N],n,cnt;
void get_primes(int n)//线性筛质数
{
for (int i=2;i<=n;i++)
{
if(!st[i]) primes[++cnt]=i;//将数存入质数数组
for(int j=1;primes[j]*i<=n;j++)
{
st[primes[j]*i]=true;//质数的倍数
if(i%primes[j]==0) break;//如果这个数是质数的倍数结束循环
}
}
}
int main()
{
cnt=0;
scanf("%d",&n);
get_primes(n);
printf("%d\n",cnt);
}