素数检查器,包括非素数

时间:2020-07-17 09:00:36

标签: python python-3.x primes

我正在尝试解决Euler项目7。

通过列出前六个质数:2、3、5、7、11和13,我们可以看到第6个质数是13。
什么是第10 001个素数?

我想到的第一件事就是使用列表长度。这是一个非常无效的解决方案,因为它花费了超过一分钟的时间。这是使用的代码。

def ch7():
    primes = []
    x = 2
    while len(primes) != 10001:
        for i in range(2, x):
            if x % i == 0:
                 break
        else:
            primes.append(x)
        x += 1
    
    print(primes[-1])

ch7()

 # Output is: 104743. 

这很好,但是我想找到更快的解决方案。因此,我做了一些研究,发现为了知道一个数字是否为质数,我们需要测试该数字是否可以被任何数字整除,直到其平方根。为了知道100是否为质数,我们不需要将其除以最多100的每个数字,但最多只能除以10。

当我实施此发现时,发生了奇怪的事情。该算法包括一些非质数。确切地说是66个。这是调整后的代码:

import math

primes = []
def ch7():
    x = 2
    while len(primes) != 10001:
        for i in range(2, math.ceil(math.sqrt(x))):
            if x % i == 0:
                break
        else:
            primes.append(x)
        x += 1
    
    print(primes[-1])

ch7()

# Output is 104009

此解决方案花了不到一秒钟的时间,但其中包含一些非质数。我使用math.ceil()来获取int而不是float,但是我认为这应该不是问题,因为它仍然可以对每个int进行测试,直到x的平方根为止。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

您的解决方案会生成一个list的质数,但除了提取最后一个元素之外,请勿将其list用于任何其他内容。我们可以将list扔掉,并通过将2作为特殊情况并仅测试奇数来减少 half 中代码的时间:

def ch7(limit=10001):  # assume limit is >= 1
    prime = 2
    number = 3
    count = 1

    while count < limit:
        for divisor in range(3, int(number ** 0.5) + 1, 2):
            if number % divisor == 0:
                break
        else:  # no break
            prime = number
            count += 1

        number += 2

    return prime

print(ch7())

但是,如果您要收集list的质数,则可以使用list来提高程序的速度(使用中的测试限制约为10%),使用这些质数作为除数而不是奇数:

def ch7(limit=10001):  # assume limit is >= 1
    primes = [2]
    number = 3

    while len(primes) < limit:
        for prime in primes:
            if prime * prime > number:  # look no further
                primes.append(number)
                break

            if number % prime == 0:  # composite
                break
        else:  # may never be needed but prime gaps can be arbitrarily large
            primes.append(number)

        number += 2

    return primes[-1]


print(ch7())

顺便说一句,即使您在注释中提到了+ 1修复问题,您的第二个解决方案仍然提供了正确答案之外的一个质数。这是由于您的代码(错误)处理质数2的方式。

相关问题