486 字
2 分钟
欧拉筛-高效筛选质数

如何高效筛素数?让我们来看看
题目:生成一个1到n范围内的质数数组
菜鸟这样做(枚举法)
从1枚举到n,判断是素数就存入数组
下面是判断方法
菜鸟:
从2枚举到n-1,如果有能整除该数的,该数就是质数。
进化版菜鸟:
菜鸟进化了,从2枚举到
高手版
埃氏筛
这样筛掉后每次下一位没被筛掉的数就都是质数
bool numlist[100000];//0代表质数,1代表非质数int prime[100000], count;void work(int n){ for(int i=2; i<=n; i++){ if(numlist[i]==0){ //如果是质数 prime[++count] = i ; //就先存入 for(int j=i; i*j<=n; j++) numlist[i*j] = 1; //然后将其平方后的所有倍数筛掉 } } return;}但是这钟筛法还不是最优,因为p的倍数会重复,所以有些数会被重复筛掉。
那么就引出了我们的最终筛法。
欧拉筛

这个筛法避免了重复筛,思路就是:每个合数只会被其最大非自身因数筛除
多说无益,先上代码:
bool numlist[100000];//0代表质数,1代表非质数int prime[100000], count;void work(int n){ for (int i = 2; i <= n; i++) { if (numlist[i]==0) ans[++count] = i;//是质数就先存入数组 for (int j = 1; j <= count && i*prime[j] <= n; j++) { numlist[prime[j] * i] = 1; //每次让i乘已放入的质数,然后标记非质数 if (i % prime[j] == 0) break;//但是如果i可以被该数整除就停止(关键) } }现在我们再来分析下。
从表可以看出,我们会筛掉每个质数p的平方之后的p的倍数,但是如果i是p的倍数,那就说明它们的乘积那个合数的最大非自身因数不是i,所以不筛。
| i 的值 | 质数表 | 筛去的数 |
|---|---|---|
| 2 | 2 | 4 |
| 3 | 2, 3 | 6, 9 |
| 4 | 2, 3 | 8 |
| 5 | 2, 3, 5 | 10, 15, 25 |
| 6 | 2, 3, 5 | 12 |
| 7 | 2, 3, 5, 7 | 14, 21, 28, 35 |
| ⋯ | ⋯ | ⋯ |
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 1373 天
部分内容可能已过时
评论