算法笔记学习记录——埃式筛
素数判断,相信大家都不陌生吧,今天我来详细介绍下关于素数判断的算法——埃式筛。
数学原理:
埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。
说简单点就是利用了素数的性质:只能被1或者它自身整除的数才是素数。那么,假设当我们判断2是素数,那么只要是2的倍数都不会是素数了;同理当我们判定3是素数时,那么只要是3的倍数都可以被排除在外了。一次类推,这就是我理解的埃式筛。
算法思想:
我们平时判定是否时素数时会在小于它的值中遍历,如果除了1和它自身之外没有能把它整除的数,则它就是素数。现在我们可以利用数学性质逆着筛它们——例如:我们知道2是素数,那么2的倍数则全部不是素数(全部标记),当判定3时(3未被标记),则3是素数,且3的倍数全部不是(同样标记),到4时,4被标记,跳过,5未被标记(是素数),5的倍数全部标记。。。。以此类推。
我们可以使用bool类型变量来开数组,我们都知道在c++中可以开的数组数量是由内存大小决定的,而且int形变量占用4个字节,而bool只占用1个字节。同时我们在这题的判断中,使用数组isprime的下标来表示数,使用isprime的储存内容(1或者0)来表示它是否是素数。
所以我们可以从2开始挨个判断,在判定一个数是素数的同时把它的倍数全部标记为不是素数,并且在之后遇到时直接跳过。
代码实现:
#include <iostream>
#include <stdio.h>
#include <string.h>
const int maxn=1e6+7;
using namespace std;
bool isprime[maxn];
void find_prime()
{
memset(isprime,true,sizeof(isprime));//一个c++自带的函数,这一行代码的功能是把isprime数组全部设置为true
isprime[0]=isprime[1]=false;//我们知道,0和1不是素数
for(int i=0;i<maxn;i++){//从0到最大数值遍历
if(isprime[i]){//未被标记,它是素数
for(int j=i*2;j<maxn;j+=i){//则这个数的倍数全部不是素数
isprime[j]=false;//用flase标记不是素数的值
}
}
}
}
int main()
{
find_prime();//直接把1到1e6+7的素数全部找出来,使用isprime记录
for(int i=0;i<1000;i++){//只是为了测试,所以只输出了1000个
if(isprime[i]){
cout<<i<<endl;
}
}
return 0;
}
运行结果: