信奥题解:质数筛选中的埃氏算法与欧拉算法的总结
质数筛选是计算机科学中一个常见的问题,许多编程竞赛和奥林匹克信息学竞赛都会涉及到。质数筛选主要有两种经典算法:埃拉托斯特尼筛法(简称埃氏筛)和欧拉筛法。这两种算法都可以有效地找出一定范围内的所有质数,但它们在实现和效率上有一些不同。
埃氏筛法(Sieve of Eratosthenes)
算法思想:
埃氏筛法通过标记合数来筛选质数。其主要思想是从2开始,将每一个质数的倍数标记为合数。算法结束时,没有被标记的数即为质数。
步骤:
- 创建一个布尔数组
isPrime
,其大小为n+1
,并初始化为true
,表示假设所有数都是质数。 - 从小到大逐个检查每个数:
- 当检查到的数为质数时(
isPrime[i]
为true
),标记其所有倍数为合数(即设置isPrime[j] = false
,其中j
从i*i
开始,步长为i
)。
- 当检查到的数为质数时(
- 最后,所有
isPrime
中仍为true
的索引即对应的质数。
复杂度:
- 时间复杂度:O(n log log n)
- 空间复杂度:O(n)
优缺点:
- 优点:实现简单,理解容易。
- 缺点:对每个质数的倍数都会进行标记,存在一些冗余操作,特别是在大范围筛选时。
欧拉筛法(Euler's Sieve)
算法思想:
欧拉筛是埃氏筛的优化版本,其通过每个合数只被其最小质因子筛掉一次,避免了重复标记,从而提高了性能。
步骤:
- 和埃氏筛一样,首先创建一个布尔数组
isPrime
,用于标记是否为质数。 - 使用一个列表
primes
保存找到的所有质数。 - 从2开始遍历,对于每个数
i
:- 如果
isPrime[i]
为true
,则i
是一个质数,将i
加入primes
。 - 对于
primes
中的每个质数p
:- 当
p*i
超过n
时停止。 - 标记
p*i
为合数。 - 如果
i
是p
的倍数,则停止内部循环。
- 当
- 如果
复杂度:
- 时间复杂度:O(n)
- 空间复杂度:O(n)
优缺点:
- 优点:效率更高,特别是在大范围的质数筛选中表现优异。
- 缺点:实现稍微复杂,需要同时维护两个数组(或者列表)。
总结
- 在需要筛选小范围的质数时,埃氏筛法的简单性和易实现性使其成为不错的选择。
- 对于大范围或更高效率的需求,欧拉筛法是更佳的选择,尽管实现稍复杂,但能大幅减少不必要的计算。
在实际应用中,选择哪种算法应结合具体数据范围和性能要求。此外,实现过程中还应考虑边界条件和优化(如跳过偶数、使用位运算等)以进一步提高性能。