线性筛素数

本文详细介绍了线性筛素数算法的基本思想与实现过程。通过确保每个合数仅被筛一次,达到线性时间复杂度。文章还提供了具体的实现代码,并解释了如何确定以某个数为最大因数的所有数。

  线性筛素数的基本思想是:每个合数只被筛一次,将被其最大因数筛掉

  假设我们依据flag数组从小到大判断每个数是否是素数,如果当前该数还未被筛掉,那么就是素数,因为在比它小的数中没有发现因数,将素数加入素数表中。对每一个数i(不论素数或合数),用它筛掉flag数组中以它为最大因数的数。因为每个数只去筛以它为最大因数的数,所以每个合数只会被一个数筛,就是它的最大因数,以此达到线性的复杂度。

  假设当前的数是i。以i为最大因数的数是哪些呢?这些数必然是i乘上一个比它小的素数(如果该数是i乘上一个比它大的素数,显然i不会是该数的最大因数;如果是i乘上一个合数x = p1*p2*...*pk pi为素数),显然通过将x的一些素因数与i相乘会得到比i大的因数)。

  假设i可以表示为素数乘积:i = p1*p2*...*pnx是一个比i小的素数(x显然已经被筛出来了,在我们的素数表中),其中i最小的素因数是p1i只有与当前素数表中p<=p1的素数相乘,得到的数y才以i为最大因数反证:如果i乘上pm得到y = i*pm,且pm>p1,那么y有因数y/p1 > i = y/pm

  所以对每一个数i,乘上素数表中不大于i的最小素因数p1的素数,将得到的数从flag数组中筛去,我们就可以在线性的时间复杂度下得到一个素数表。

  代码:

 

 1 int flag[10001],p[10001],pnum;
 2 
 3 void createP(){
 4     pnum=0;
 5     for(int i=0; i<=10000; i++){
 6         flag[i]=0;
 7     }
 8     for(int i=2; i<=10000; i++){
 9         if(flag[i]==0){
10             p[pnum++]=i;
11         }
12         for(int j=0; j<pnum && p[j]*i<=10000; j++){
13             flag[p[j]*i]=1;
14             if(i%p[j]==0)
15                 break;
16         }
17     }
18 }

 

 

 

转载于:https://www.cnblogs.com/Lattexiaoyu/archive/2012/07/13/2589788.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值