报告小于n的所有素数

时间:2012-03-15 07:04:06

标签: primes

我需要打印小于给定数字n的所有素数。我可以使用Eratothenes筛,但该算法的运行时间不是O(n)。这个问题有没有O(n)时间解决方案?

2 个答案:

答案 0 :(得分:1)

Eratosthenes的Sieve具有时间复杂度O(n log log n)。函数log log n增长非常缓慢;例如,log(log(10 ^ 9))= 3.这意味着你可以有效地将时间复杂度的日志对数部分视为常量,并忽略它,给出时间复杂度“接近”O(n)

有各种算法在时间O(n)或O(n / log log n)下运行,包括Pritchard的轮筛和Atkins筛子。但是,恒定因素通常会使这些算法在实践中比Eratosthenes的Sieve慢。除非你需要极速的速度,并且你知道自己在做什么,并且愿意花很多时间去做,所以实际的答案就是Eratosthenes的筛子。

你的问题是你要打印素数列表。在这种情况下,输出将主导您选择的任何算法的运行时间。所以,帮自己一个忙,并实施一个简单的Eratosthenes筛选。

答案 1 :(得分:0)

我认为你不会找到一个算法来检查具有O(n)时间复杂度的素数的任意数。我很确定NSA(以及任何其他处理加密问题的组织)会对此不满意: - )

获得O(n)或更好的方法的唯一方法是预先计算(例如)前五千万个素数(或使用someone else's already-precalculated list)并将其用作查找。我在本地有这样一个文件,只需要在它上面运行grep即可查看该数字是否为素数。它对任意数字没有帮助,但我很少使用那些大数字。当然,加密人会认为这样的名单对于他们的目的来说很小。

而且,如果你把它变成一个位图(前五千万个素数约为120M),你甚至可以通过简单地将数字转换为字节偏移和位掩码来降低O(1)的复杂度 - 一对位移和/或按位运算。

然而,在O(n)时间复杂度下,获得低于某个n的素数的列表肯定是可行的。 Atkin and Bernstein paper详细说明Sieve of Atkin声明:

  

我们引入了一种算法,该算法使用O(N/log(log(N)))个加法来计算最多为N的素数...

实际上比O(n)稍微更好

但是,它仍然不太可能与查找解决方案竞争。我的建议是使用Atkin或Eratosthenes来制作一个列表 - 这并不重要,因为你只会这样做一次所以性能不是很关键。

然后使用列表本身来检查素性。