一.埃氏筛法
首先,构造一个序列:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
取序列数2,它一定是素数,然后用2把序列的2的倍数筛掉:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
取新序列数3,然后用3把序列的3的倍数筛掉:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
取新序列的数5,然后用5把序列的5的倍数筛掉:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
不断筛下去,就可以得到所有的素数。
(注:红色数字既不是素数,也不是质数 绿色数字是质数 蓝色数字是素数)
基础思想 素数的倍数一定不是素数
实现 从小至大枚举质数x,把x的倍数都标记为非质数
#include<iostream>
using namespace std;
int main()
{
int a[100005]={0}; //标记为 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; //标记为 1
}
}
}
for(i=2;i<=100000;i++)
{
if(a[i]==0)
{
cout<<i<<endl; //输出质数
}
}
return 0;
}
二. 欧拉筛法求素数
欧拉筛法是一种高效的求素数的方法。
首先,构造一个序列:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
取序列数2,它一定是素数,然后把2提出,通过 2*2 将4筛去:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
2
取新序列数3,然后把3提出,通过2*3 ,3*3将6,9筛去:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
2 3
取新序列的数5,然后然后把5提出,通过3*5,2*5 将15,10筛去:
0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
2 3 5
不断筛下去,就可以得到所有的素数。
(注:红色数字既不是素数,也不是质数 绿色数字是质数 蓝色数字是素数)
基本思想 将一个数拆分成两个数的乘积,然后每次以a*b的形式去筛除c,且在a相同时b不相同,则可以保证c只被筛除一次。(a为c的最小质因子)
#include<iostream>
using namespace std;
int main()
{
int a[100005]={0},pri[10005]; //pri[10005] : 存储质数
int i,j,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;
}