【发布时间】:2012-05-03 05:38:35
【问题描述】:
这是有问题的算法,伪代码:
list.add(2)
for (i = 3 to n)
isPrime=true
for each (j in list)
if ((i mod j) = 0)
isPrime=false
break
if (isPrime)
list.add(i)
return list
我的 TA 今天告诉我这个算法的复杂度为 O(n^2),但我很确定这是不正确的,特别是考虑到大约有 n/ln(n) 个素数直到任何 n,因此,如果 n 本身是素数,则内部循环在其最后一次迭代中的迭代次数不会超过 n/ln(n) 次。但是我认为它实际上低于 O(n^2/ln(n)) ,但我不确定如何确定它实际上是什么。例如,每个偶数只迭代第二个循环两次。
【问题讨论】:
-
现在,这完全是错误的。当它发现它们是复合的时,它会将数字添加到素数列表中。当且仅当您检查当前已知的素数(直到 sqrt(n))并且它们中的 none 均分新候选时,它们才是素数。有了这个固定值,你就大致正确了——素数定理说 1/log(n) 质数小于 n,所以你将测试 ~1/log(n) 数,而不是每次迭代中的 N 个数。
-
过去有一段时间分析 O() 变得毫无意义;你已经通过了。但是,这个算法是错误的,所以也许你的算法意思会有所不同。
-
糟糕——这应该是 N/log(N),而不是 1/Log(N)。问题在于他几乎是对的——log(N) 增长如此缓慢,以至于它非常对整体复杂性几乎没有影响。
-
我修正了算法。我的直觉也告诉我实际的复杂度将在 O(x * sqrt(x)) 附近
-
您可以轻松地从循环中省略偶数,因为测试它们没有意义;它们总是复合的(因此
for (i = 3 to n step 2)节省了一些时间)。
标签: algorithm complexity-theory primes