如果我们想知道从零到一个数有哪些质数,我们首先会想到运用枚举法,将小于这个数的每个数都相乘一遍,这样的做法会大大降低我们程序的质数,增加时间,事实上,在我们之前就有许多人尝试运用另外的思维,当然,他们成功了,这就徒手搓出我们现在所使用的几种筛法,而我们现在要讲的正式四种筛法中的中间两种,欧拉筛与埃氏筛
欧拉筛法
步骤:
1.2到某数N之间的自然数列出来,标准格式为:2,3,4,...,N【1】
2.设为第一个素数
3.2的倍数全部剔除
4.到下一个未被剔除的数,将其设为第二个素数;
5.该数的倍数全部剔除
6.复第4、5步,直到所有小于某数的素数都被找出来
【1】:为什么第一个数是2而不是0?//寻找质数从2开始1和0既不是质数也不是合数
图表:
代码实现:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[100005]={0},pri[10005];
int i,j,num;
num=0;
for(i=2;i<=100000;i++)
{
if(a[i]==0)
{
pri[++num]=i;
}
for(j=1;j<=num;j++)
{
if(i*pri[j]>100000)
{
break;
}
a[i*pri[j]]=1;
if(i%pri[j]==0)
{
break;
}
}
}
for(i=1;i<=num;i++)
{
cout<<pri[i]<<endl;
}
return 0;
}
=========================================================================
埃氏筛法:
步骤:
-
2到某数N之间的自然数列出来,标准格式为:2,3,4,...,N
-
设第一个数是素数
-
枚举所有p的倍数(2p,3p,4p,…),标记为非质数(合数);
-
找到下一个 没有标记 且 大于p 的数。如果没有,结束运算;如果有,将该值赋予p,重复步骤4;
-
运算结束后,剩下所有未标记的数都是找到的质数。
//我觉得这两个方法大致相同
图表:
图像来源于;(14条消息) 埃拉托色尼筛选法巧解质数问题(埃氏筛法求解素数问题)_质数筛选法动图_吴雨4的博客-CSDN博客
代码实现:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[100005]={0};
int i,j;
for(i=2;i<=100000/i;i++)
{
if(a[i]==0)
{
for(j=2;i*j<=100000;j++)
{
a[i*j]=1;
}
}
}
for(i=2;i<=100000;i++)
{
if(a[i]==0)
{
cout<<i<<endl;
}
}
return 0;
}