【问题标题】:Sieve of Eratosthenes in PythonPython中的埃拉托色尼筛法
【发布时间】:2013-06-27 21:51:34
【问题描述】:

我正在尝试编写一个 python 函数来返回小于给定值的素数和所有素数的值。我需要使用埃拉托色尼筛算法。我相信我在函数中遗漏了一些东西 - 例如,当我想找到 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

【问题讨论】:

    标签: python sieve-of-eratosthenes


    【解决方案1】:

    “我被告知我需要使用平方根”。你为什么这么认为?通常 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,包括101

    【讨论】:

      【解决方案2】:

      您的逻辑是正确的,除了for 循环。它在到达sqrt(n)-1 后终止。对于p(100),它只能从 2 运行到 9。因此你只能得到质数直到 9。

      【讨论】:

      • 我应该在这里提到,您的逻辑确实找到了直到 n 的所有素数,即 is_p 仅在 for 循环结束时具有 True 的素数索引。唯一的问题是yield 调用的次数不够。
      • 感谢您的提示!真的很感激!
      【解决方案3】:

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

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

      【讨论】:

      • 感谢您的提示!真的很感激!
      猜你喜欢
      • 1970-01-01
      • 2011-12-16
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多