繁体   English   中英

python中的质数生成代码

[英]prime number generation code in python

我正在尝试以下方法来生成素数:

primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
    if all(candidate % prime for prime in primes if prime**2 <= candidate):
        primes.append(candidate)
    candidate += 2

但是,这比我以前的代码要慢得多,在我以前的代码中我没有使用all函数,而是自己进行检查,如下所示:

primes = [2]
candidate = 3
MILLION = 1000000
while candidate < MILLION:
    can_be_prime = True
    for p in primes:
        if p**2 > candidate:
            break
        elif candidate % p == 0:
            can_be_prime = False
            break
    if can_be_prime:
        primes.append(candidate)
    candidate += 2

当第二个在10秒内结束时,第一个要花很长时间才能完成。 有人可以帮助我理解为什么第一个数字在第一个100000个数字之后开始如此缓慢地输出吗?

当你的想法,使用发电机表达缩短了代码和any好,他们是不等价的。 特别是,在较长的解决方案中,您要迭代素数的(排序的)列表,并在找到p ** 2 > candidate为真的素数后立即中断迭代。

但是,在生成器表达式中, x for p in primes if p ** 2 <= candidate ,则尝试使用x for p in primes if p ** 2 <= candidate进行此检查。 不幸的是,这是一样的。 即使检查失败,发电机仍会继续遍历剩下的素数,执行的是p ** 2 每单质,在外部的每次迭代 while循环。

如果您编写的方式有所不同,则可以验证这是问题所在:

def getPrimes (candidate):
    for p in primes:
        if p ** 2 > candidate:
            break
        yield p

while candidate < MILLION:
    if all(candidate % prime for prime in getPrimes(candidate)):
        primes.append(candidate)
    candidate += 2

因此,现在,我们在较长版本中使用相同的想法,并在达到p ** 2 > candidate为真的primes终止primes的迭代。 这样,我们可以从更长的解决方案中获得更快的速度。

我们实际上可以使用6n +/- 1规则生成素数。 例如,如果要生成给定数字的质数:

def primes(N):
    if N == 2:
        primes = [2]
    elif N >= 3:
        primes = [2, 3]
    else:
        return None
    for i in range(6, N):
        if i % 6 == 0:
            left = i - 1
            right = i + 1
            if all(left % p != 0 for p in primes):
                primes.append(left)
            if all(right % p != 0 for p in primes):
                primes.append(right)
    return primes

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM