java筛选法求质数_线性筛选法求质数

还是之前的问题,求出MAXSIZE以内的所以质数

下面我们看下原理

所有的合数都可以分解为两个数的乘积,那么我们建立一个isPrime[MAXSIZE+1]的表,先把所有的元素设置成默认为是质数,true,设置两重循环,将i*j处的值设置成false,这样最后得到的是true元素对应的角标就是质数了,下面附上代码:

#include #include

using namespacestd;#define max 99999

int prime[max+1];bool isPrime[max+1];int count = 0;intmain()

{for (int i = 0;i <= max;i++)

{

prime[i]= 0;

isPrime[i]= true;

}

clock_t start,end;//用于计时

start =clock() ;for (int i = 2;i <= max;i++)

{for(int j = 2;j <= max && i*j <= max;j++)

{

isPrime[i*j] = false;

}

}

end=clock();for(int i = 2;i <= max;i++)

{if(isPrime[i])

{

cout<

}

}

cout<

}

这里我们可以看到,其实没有经过什么优化,让我们看戏程序的效率:

8b81816eac6d90a77c5678c10751de65.png

这个效率已经很高很高了,比之前的筛选法还要高了,下面我们看下在这个算法中还能怎么样去减少循环次数,减小程序的时间复杂度

设想下,在2*4 = 8处和4*2 = 8处,或者 2* 12 = 24和3*8 = 24处,都分别进行了多次赋值,这样看来,效率有所降低,下面是我们优化过的代码,

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

#include #include

using namespacestd;#define max 99999

int prime[max+1];bool isPrime[max+1];int count = 0;intmain()

{//将数组初始化

for (int i = 0;i <= max;i++)

{

prime[i]= 0;

isPrime[i]= true;

}

clock_t start,end;//用于计时

start =clock() ;for (int i = 2;i <= max;i++)

{if(isPrime[i])

{

prime[count++] =i;

}for(int j = 0;j < count && i*prime[j] <= max;j++)

{

isPrime[i*prime[j]] = false;if (i % prime[j] == 0)

{break;

}

}

}

end=clock();for(int i = 2;i <= max;i++)

{if(isPrime[i])

{

cout<

}

}

cout<

}

优化过的代码

通过prime数组保存已经得到的质数,然后用这些质数去乘以i得到合数,并将该合数对应的位置置为false,关键还有一个

if (i % prime[j] == 0)

{break;

}

操作,比如,当i为8的时候,搜索到2,也就是2*8 = 16,处置为false就可以了,跳出J的循环,因为假如到8*3=24的话 24 = 2*12,可以由一个更大的合数得到,这样就可以减少循环次数,优化时间复杂度,下面看程序运行结果:

94310d72c25d8d0f19997914b1ee89ed.png

这个时间,你懂的!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值