【算法】素数筛
2024-04-22 23:00:46
引子
本文探讨寻找从2到n所有质数的几种方法,并在复杂度上进行比较。
1. 常规的寻找质数法
思想:对于每一个数字,从2开始枚举到该数字的算术平方根处,若存在某个枚举到的数能整除当前数字,则该数字非质数。
C语言代码段如下:
1 | int isPrime; |
该寻找方法,复杂度为$O(n\sqrt{n})$。
2. 埃拉托斯特尼筛法
思想:
- 维护一个表,表项为0代表该表项下标是质数。
- 已知2是最小的质数,在表中将所有以2的倍数为下标的表项标注为1,寻找表项为0的最小下标,该下标为一个质数。
- 标记以该质数倍数为下标的表项,接着寻找表项为0的最小下标,该下标同样也是一个质数。
- 回到第二步,做类似操作。
C语言代码段如下:
1 | int prime[n] = {0}; |
该寻找方法,复杂度为$O(nloglogn)$。根据素数定理,可以通过积分算出这个复杂度,详情参考这里。
该方法存在问题,比如在遍历到2、3时,下标为12的表项,都会经历一次赋值操作。
3. 欧拉筛法
思想:
- 维护一个记录表,表项为0代表该表项下标是质数。维护一个质数表,装质数本身。
- 已知2是最小的质数,放入质数表。
- 从2开始,每个数都与质数表里的数相乘,将记录表对应下标表项修改为1。
- 若遍历到某个数,能被质数表中某一质数整除,则回到第二步,做类似操作。
C语言程序如下:
1 |
|
该寻找方法,复杂度为$O(n)$。