参考:http://blog.csdn.net/once_hnu/article/details/6302283
素数,就是只有1和自身两个约数的正整数。2是最小的素数。根据定义,我们就可以直接判断一个数字n是否是素数。优化后的复杂度是O(n*sqrt(n))。原因的话:http://www.goodgoodstudy.pw/?p=38 ,自己也可以稍作思考。但是,在大规模的数据范围时,这个算法会耗时太多,显得十分低效!
下面介绍第二种较为高效的算法-----筛法。
具体筛法是:先把n个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛法”,简称“筛法”。
#include<cmath> // 1:这是最原始的筛法 #include<cstdio> #define Max 30 bool prime[Max]; void IsPrime(){ prime[0]=prime[1]=0;prime[2]=1; for(int i=3;i<Max;i++) prime[i]=i%2==0?0:1; int t=(int)sqrt(Max*1.0); for(int i=3;i<=t;i++) if(prime[i]) for(int j=i+i;j<Max;j+=i) prime[j]=0; } int main() { IsPrime(); for(int i=1;i<=30;++i) printf("%d ",prime[i]); }
下面是比较快的筛法
- //2:优化后的筛法,手动地模拟原始筛法就可以发现,某个数字可能被不止一次地删去
- // 优化后的筛法就可以避免这种不必要的删去操作
#include<cmath> #include<cstdio> #define Max 30 bool prime[Max]; void IsPrime(){ prime[0]=prime[1]=0;prime[2]=1; for(int i=3;i<Max;i++) prime[i]=i%2==0?0:1; int t=(int)sqrt(Max*1.0); for(int i=3;i<=t;i++) if(prime[i]) for(int j=i*i;j<Max;j+=2*i)//优化 prime[j]=0; } int main() { IsPrime(); for(int i=1;i<=30;++i) printf("%d ",prime[i]); }
时间: 2024-12-07 11:32:06