欧拉筛和埃氏筛是较方便的质数查找法,与其他常见的找质数方法来说更快速,简洁。
埃氏筛
埃氏筛的思想:从2开始,将每个质数的各个倍数标记为合数,从而在自然数n以内找出全部质数。
例如寻找1~20中的所有质数,我们从2开始,依次往后进行判断这个数是否为质数,如果是质数,就将这个质数的倍数标记,随后寻找没有被标记过的数是否为质数,如果不是质数,则标记,不断重复这样的操作,知道遍历1~20所有的数字。
代码实现:
#include<iostream>
using namespace std;
int main()
{
int a[25]={0};
for(int i=2;i<=20/i;i++)
{
if(a[i]==0)//判断是否为质数
{
for(int j=2;i*j<=20;j++)
{
a[i*j]=1;//标记当前质数的倍数
}
}
}
for(int i=2;i<=20;i++)//遍历2~20所有数字
{
if(a[i]==0)//判断是否为质数
{
cout<<i<<endl;//输出所有质数
}
}
cout<<sum;
return 0;
}
但它在标记质数的倍数时,会进行重复标记。例如:12,12的质因子有2、3,在寻找2、3这两个质数的倍数时,12将会被标记很多次,从而影响到程序执行的效率。
而欧拉筛,正好可以解决重复标记的问题。
欧拉筛
欧拉筛是一种高效的找质数方法,又称线性筛法。
它的核心思想与埃氏筛法有一点不同,埃氏筛法是将所有质数的倍数标记,会有重复标记的现象。欧拉筛找出第一个质数后会继续判断下一个数,例如1~20,从2开始,2是质数,3也是质数,下一个数字4是合数,它的最小质因子是2,于是4被标记。
它们的区别主要体现在标记上,埃氏筛会用找到的所有质数标记合数,会重复,欧拉筛只会用这个合数的最小质因子来筛选,效率上有很大区别。
欧拉筛代码实现:
#include <iostream>
using namespace std;
int main()
{
int a[205]={0},pri[25];
int i,j,num;
num=0;//num既是pri数组的下标,也是质数的个数
for(int i=2;i<=20;i++)
{
if(a[i]==0)
{
pri[++num]=i;
}
for(int j=1;j<=num;j++)
{
if(i*pri[j]>20)//找1~20这个范围内质数的倍数
{
break;
}
a[i*pri[j]]=1;//标记
if(i%pri[j]==0)//找出i的最小质因子并判断
{
break;
}
}
}
for(int i=1;i<=num;i++)
{
cout<<pri[i]<<endl;
}
return 0;
}