求某区间内所有素数的算法(简单到进阶)
一、寻找素数
1、暴力求解。时间复杂度:n根号n
枚举每个数,判断是否有正整数能整除这个数。
for(int i=2;i<n;i++)
{
int flag=0;
for(int j=2;j*j<=i;j++)
{
if(i%j==0) { flag=1; break; }
}
if(flag==0)
a[k++]=i;//存放素数i
}
当n=1000000时,用时0.245s
2、普通筛选。时间复杂度: nlogn
既然每个合数必然能分解成多个素数的成绩,那么在搜索到一个素数的时候,我们就把他们的倍数标记为合数
for(int i=2;i<=n;i++)
{
if(p[i]==0)
{
a[k++]=i;//存放素数i
for(int j=2;j*i<=n;j++)
p[j*i]=1;
}
}
当n=100000时,用时0.029s
3、线性筛法。时间复杂度:n
普通筛法中,一个合数可能被多个素数筛掉,也就是说可能重复被筛,浪费了时间。线性筛法中将合数表示成最小素数*一个数的形式。
枚举到i,设p是i的最小素因子,p1<p2<…<p,将p1*i,p2*i,…,p*i标记为合数。
for(int i=2;i<=n;i++)
{
if(p[i]==0)
a[k++]=i;
for(int j=0;j<k&&i*a[j]<=n;j++)
{
p[i*a[j]]=1;
if(i%a[j]==0) break;
}
}
当n=1000000时,用时0.013s。