【问题标题】:Finding the 10001st prime - how to optimize?寻找第 10001 个素数 - 如何优化?
【发布时间】:2015-11-26 19:47:17
【问题描述】:

Project Euler 问题 7 说:

通过列出前六个素数:2、3、5、7、11 和 13,我们可以 看到第 6 个素数是 13。第 10001 个素数是多少?

这是我用 Python 编写的代码:

def primes(n):
    primes = []
    attempt = 3
    while len(primes) < (n-1):
        for i in range(len(primes)):
            if attempt % primes[i] == 0:
                attempt += 2
                break
        else:
            primes.append(attempt)
            print (primes)
    return (primes)

在测试一个数字时,如果它发现该数字可以被列表中的一个素数整除,则 for 循环会中断,并从一个更大的数字重新开始。如果它不可整除,则将其添加到素数列表中。这一直持续到列表尽可能大(在本例中为 10000,我省略了 2,因此列表的最后一个成员是第 10001 个素数)

问题是这非常慢。我已经看到其他解决方案显然可以解决这个问题,如果不是更少的话。有什么方法可以让这件事变得更有趣?

【问题讨论】:

  • 搜索“Prime sieve”一词可能会给您带来有用的结果。
  • 另外,只需使用numpy 对数字进行简单更改即可加快速度,不要使用那个 for 循环,使用其他方式。
  • 如果这是工作代码,请尝试 codereview.stackexchange.com
  • 您应该在Code Review 上发布此内容,和/或在Computer Science 上发布有关算法的信息。

标签: python performance optimization primes


【解决方案1】:

这些是优化问题,因此您不希望每次更新列表时都打印。另一件事是根本不使用列表,因为内存效率不是很高。您应该改用生成器。它非常快,而且您不会使用列表来消耗内存。下面是用于此目的的代码,请注意如何使用 yield 关键字将 count_primes 函数转换为生成器。

def is_prime(num):
    """
    Checks if a number is prime
    """
    prime_counter = 1
    for x in range(1, num):
        if num % x == 0:
            prime_counter += 1
        if prime_counter > 2:
            return False
    return True


def count_primes():
    """
    Counts primes until PRIMES_TO_COUNT
    is reached
    """
    PRIMES_TO_COUNT = 1000       # Modify this value
    prime_counter_num = 0
    start_point_num = 1
    while True:
        if is_prime(start_point_num):
            if prime_counter_num == PRIMES_TO_COUNT:
                yield start_point_num
                print "This is the %dth prime number: %s" \
                      % (prime_counter_num, start_point_num)
                break
            prime_counter_num += 1
        start_point_num += 1


if __name__ == '__main__':
    for prime_number in count_primes():
        print prime_number

希望这对您有所帮助! Python generators!

【讨论】:

    【解决方案2】:

    您可以检查所有 6n±1 形式的数字,而不是检查每个奇数,因为所有素数都是这种形式。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    相关资源
    最近更新 更多