【问题标题】:Prime Sieve/pairs in a range一定范围内的素筛/对
【发布时间】:2017-01-16 21:15:27
【问题描述】:

我正在尝试编写一个素数筛生成器,将其转换为打印列表,然后打印给定范围内的素数。我很确定我的对数是正确的,但由于某种原因,我在非素数的素数列表中得到了一些额外的值。 (我立即发现了这一点,因为我在输出中的最后一个值是 3599,它不是素数)。 我不确定我是否有某种逻辑错误,所以任何帮助都会很棒

def sieve(n):
     a = [True] * (n)
     a[0] = a[1] = False
     for (i, isPrime) in enumerate(a):
         if isPrime:
              yield i
             for n in range(i*i, n, i):
                 a[n] = False


 def pairs(li):
     pair = 0
     for i, x in enumerate(li):
         if i < len(li)-1:
             if li[i] + 2 == li[i+1]:
                 pair += 1
     return pair

 p_3600 = list(sieve(3600))

 ans = [vals for vals in p_3600 if vals > 1600]

 print ans

 print "pairs:", pairs(ans)

【问题讨论】:

  • @Jean-FrançoisFabre 是的,你是对的,很抱歉。我只是在搞乱界限,看看我是否能弄清楚为什么我会得到一些额外的数字。那应该是n。

标签: python primes sieve-of-eratosthenes sieve


【解决方案1】:

您的筛子功能不正确。您将所有数字标记为非质数,从“2”开始。 您需要从素数的下一个倍数开始,即prime*prime

因此,您必须从i*i 而不是i 开始(我使用了i*2,它有效但多余,因为i==2 时已经被第一个循环覆盖)

def sieve(n):
    a = [True] * n
    a[0] = a[1] = False
    for (i, isPrime) in enumerate(a):
     if isPrime:
        yield i
        for j in range(i*i, n, i):
            a[j] = False

为了测试您的列表,我建议您添加一个主要测试,以便您确定:

# make sure it works: time-costly but reassuring
import math
for i in ans:
    si = int(math.sqrt(i))+1
    for j in range(2,si):
        if i%j==0:
            raise Exception("%d is not prime (%d)" % (i,j))

【讨论】:

  • 从 i * i 开始内循环会更快
  • 这将是最好的做法:)
  • 啊。你是对的。我相信你实际上甚至可以从 i*i 开始。奇怪的是,它也没有修复输出。不过还是谢谢你。
  • 在我尝试过的小样本上输出似乎没问题。您计算距离为 2 的 2 个素数的方法可以正常工作。问题是当你有 3、5、7 时,你会得到 2 对。也许你想跳过 5,7 因为已经属于 3,5?
  • 我说的是真正的筛分功能。当我打印 1600 到 3600 百之间的素数列表时,我得到了所有素数,还有一些不是素数的额外数字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 2011-09-21
相关资源
最近更新 更多