改善Euler#10的运行时间

时间:2014-11-04 02:22:48

标签: python performance

所以我在小规模上攻击一个看似非常简单的欧拉问题,但是一旦我将它提升到我应该做的数字,代码就会永远运行。这是个问题:

  

低于10的素数之和为2 + 3 + 5 + 7 = 17.

     

找出200万以下所有素数的总和。

我是用Python做的。我可以等几个小时来运行代码,但我宁愿找到更有效的方法来解决这个问题。这是我在Python中的代码:

x = 1;
summ = 0;

while x <= 2000000:
    y = 1;
    z = 0;

    while x >= y:    
        if x % y == 0:
            z += 1;   

        y += 1;

    if z == 2:
        summ += x

    x += 1;

print summ;

2 个答案:

答案 0 :(得分:0)

显然,这个帐篷中的长杆首先计算了素数列表。对于像这样的人为情况,你可以得到别人的名单(比如this一个),然后将其删除并在几秒钟内加上数字。

但在我看来,那是不正确的。在这种情况下,请尝试this SO回答中提到的atkin筛子。

答案 1 :(得分:0)

如评论中所述,实施Eratosthenes筛选将是一个更好的选择。在这种情况下,它占用O(n)个额外空间,这是一个长度约为200万的数组。它也在O(n)中运行,这比在O(n²)中运行的实现速度更快。

我最初是用JavaScript写的,所以忍受我的python:

max = 2000000    # we only need to check the first 2 million numbers
numbers = []
sum = 0

for i in range(2, max):    # 0 and 1 are not primes
    numbers.append(i)      # fill our blank list
for p in range(2, max):
    if numbers[p - 2] != -1:   # if p (our array stays at 2, not 0) is not -1
        # it is prime, so add it to our sum              
        sum += numbers[p - 2]
        # now, we need to mark every multiple of p as composite, starting at 2p
        c = 2 * p
        while c < max:
            # we'll mark composite numbers as -1
            numbers[c - 2] = -1
            # increment the count to 3p, 4p, 5p, ... np
            c += p

print(sum)

这里唯一令人困惑的部分可能就是我使用numbers[p - 2]的原因。那是因为我跳过了0和1,意思是2在索引0处。换句话说,所有东西都转移到了2个索引。