筛选法统计素数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LightInDarkness/article/details/82562034

       学习到一种高效的筛选素数的方法——埃拉托色尼筛选法,如果要选出[2, n]范围内的素数,可以参考以下步骤:

       1.构造一个[2, n]范围的数组,全部标记为1(true)。

       2.删除掉数组中的非素数,将其标记为0(false)。

          ①:删除2的倍数

          ②:删除3的倍数

          ③:删除4的倍数(没有必要,已经在①中删除了)

          ④:删除5的倍数

          ⑤:……

       3.直到不能继续删除为止。如此留下的就是质数了。

       原理是显而易见的,没有必要多做解释。先上代码:

#include<iostream>

#define n 10000

using namespace std;

int main(){
	int prime[n + 1];
	//初始化数组 
	for(int i = 0; i < n + 1; i++)
		prime[i] = 1;
	//筛选素数 
	for(int i = 2; i * i <= n; i++){
		if(prime[i] == 1){
			int j = i * i;
			while(j <= n){
				prime[j] = 0;
				j += i;
			}
		}
	}
	//输出 
	for(int i = 2; i < n + 1; i++)
		if(prime[i] == 1)
			cout << i << '\t';
}

       先看这部分代码:

if(prime[i] == 1){
	int j = i * i;
	while(j <= n){
		prime[j] = 0;
		j += i;
	}
}

       意思是如果i是素数,会去除i * i, i * (i + 1), i * (i + 2), i * (i + 3), ...... , i * (i + m)。(其中i * (i + m) <= n)

       那2i, 3i, 4i, ...... i * (i - 1)怎么办呢?实际上,我们已经早就把这些数删掉了。因为我们在去除i的倍数以前,早就已经去除了2, 3, 4, ......, i - 1的倍数。而我们省去的那部分数也正是这些数的倍数,所以就无需再次删除了。

       在理解了这个的基础上,我们再来看看for循环中i * i <= n的条件。实际上就是要求i <= floor(√n)。当i == floor(√n)时,只需要处理i * i( <= n)之后i的倍数即可, 前面的已经被其他数的倍数去除了。此时若i += 1,那么i实际上删除的倍数则在n之后,对于题目要求而言就没什么必要了。

猜你喜欢

转载自blog.csdn.net/LightInDarkness/article/details/82562034