素数筛选-埃拉托斯特尼筛法
首先,默认大家都知道素数(质数)吧,就是对于一个正整数n,如果能且仅能被1和n整除,那么这个数n为素数~ps:0,1不是质数。
那么对于判断一个数是否为素数,起初的做法是我们从i=2开始,判断n%i!=0,然后i++一直到n-1,如果全部满足不能整除那么此n为素数。
大家都知道其实不用判断到n-1,只要到sqrt(n)就ok了,这是为什么呢,这里就不解释了- -(本人虽然菜鸟,但还是觉得好啰嗦)
对于任何一个整数n可以通过以上方法来判断n是否为素数,若如果要你找出从1~n中所有的素数,那是不是对于每个n都要去判断一次呢?
假如n=1000000;那么这个算法的时间复杂度为o(n*sqrt(n)),这个数有多大我就不解释了。。。那是你的计算机跑几分钟都跑不完的。所以
我在这里介绍一种时间为o(n*lgn)的算法,它的名字叫做:埃拉托斯特尼筛法。
终于切入正题,其实这种筛选法特别好理解。首先我们把所有的数标记为素数(true),就是我们从2开始,找出所有2的倍数,把它标记为不是素数(false)(当然不是素数),再找到3,找出所有3的倍数,也标记为不是素数(false),再找到下一个标记为(true)的数k,再去找到所有k的倍数,标记为(false),依次类推...那么剩下来的数就都是素数了.如果你还不理解就看代码吧,写的很详细。(visit[i]用来判断i是素数还是合数)
View Code
1 //==================================================================== 2 //Name :埃拉托斯特尼筛法---列出小于给定数的所有素数的算法 3 //Author :hxf 4 //copyright :http://www.cnblogs.com/Free-rein/ 5 //Description:时间复杂度O(n*lgn) 6 //Data :2012.7.27 7 //======================================================================== 8 #include<iostream> 9 #include<algorithm> 10 #include<stdio.h> 11 #include<math.h> 12 #include<string.h> 13 #include <vector> 14 #include <stack> 15 #define MAX 200002//prime的数组大小 16 #define inf 1499999//prime的数据范围 17 using namespace std; 18 int prime[MAX];//质数的数组,从1~MAX 19 bool visit[inf];//判断第i个数是否为质数 20 void get_prime() 21 { 22 int temp=1;//代表prime的下标,共temp-1个数 23 for(int i=2;i<=inf;i++) 24 visit[i]=true; 25 for(int i=2;i*i<=inf;i++) 26 { 27 if(visit[i]==true)//找到一个数为素数 28 { 29 for(int j=i;i*j<=inf;j++)//标记i的所有倍数为false 30 visit[i*j]=false; 31 } 32 } 33 for(int i=2;i<=inf;i++) 34 if(visit[i]==true) 35 { 36 prime[temp++]=i;//把留下来的素数存下来就ok了 37 } 38 } 39 int main() 40 { 41 return 0; 42 }