在Python中的Eratosthenes筛选

时间:2013-06-27 21:51:34

标签: python sieve-of-eratosthenes

我正在尝试编写一个python函数来返回小于给定值的素数和所有素数的值。我需要使用Sieve of Eratosthenes算法。我相信我在功能中缺少一些东西 - 例如,当我想找到100以下的素数时。我得到的是2,3,5,7。我知道如果我不使用“平方根” ,我可以得到我需要的所有素数;但我被告知我需要在那里包括平方根。有人可以看看我的代码,让我知道我错过了什么?谢谢你的时间。

def p(n):
is_p=[False]*2 + [True]*(n-1)
for i in range(2, int(n**0.5)):
    if is_p[i]:
        yield i
        for j in range(i*i, n, i):
            is_p[j] = False

3 个答案:

答案 0 :(得分:4)

“我被告知我需要使用平方根”。你为什么这么认为?通常,E的筛子用于从列表中删除所有“非素数”;您可以通过查找素数,然后检查列表中所有素数的倍数来完成此操作。下一个“未检查”的数字是您的下一个素数 - 您报告它(使用yield),然后再次继续检查。您只需要检查小于平方根的因子 - 大于平方根的因子具有小于平方根的相应因子,因此它们已被找到。

不幸的是,当打印出素数时,你不能“停在中间”。例如,101是素数;但如果你只循环到11,你将永远不会发现它在那里。所以需要有两个步骤:

1)循环遍历所有“可能的倍数” - 在这里你可以“只到达平方根”

2)检查列表中所有尚未检查过的号码 - 这里你必须“一路走来”

这使得以下代码:

def p(n):
  is_p=[False]*2 + [True]*(n-1)
  for i in range(2, int(n**0.5)):
    if is_p[i]:
        for j in range(i*i, n, i):
            is_p[j] = False
  for i in range(2, n):
    if is_p[i]:
      yield i

print list(p(102))

结果是一系列素数列表,包括101

答案 1 :(得分:2)

for循环外,您的逻辑是正确的。它在到达sqrt(n)-1后终止。对于p(100),它将仅从2到9运行。因此,只有到9才能获得素数。

答案 2 :(得分:1)

您对平方根的使用会提前终止您的结果。如果你想要yield所有素数高达100,你的循环必须达到100。

您的代码中不需要平方根,因为它隐含在您的第二个for循环中。如果i*i < ni < sqrt(n)