Python 改进Euler#10的运行时间
所以我在攻克一个Euler问题,这个问题在小范围内看起来很简单,但一旦我把它提升到我应该做的数字,代码就会永远运行下去。问题是: 低于10的素数之和为2+3+5+7=17 求200万以下所有素数之和 我是用Python做的。我可以等几个小时让代码运行,但我更愿意找到一种更有效的方法。以下是我的Python代码:Python 改进Euler#10的运行时间,python,performance,math,sieve-of-eratosthenes,Python,Performance,Math,Sieve Of Eratosthenes,所以我在攻克一个Euler问题,这个问题在小范围内看起来很简单,但一旦我把它提升到我应该做的数字,代码就会永远运行下去。问题是: 低于10的素数之和为2+3+5+7=17 求200万以下所有素数之和 我是用Python做的。我可以等几个小时让代码运行,但我更愿意找到一种更有效的方法。以下是我的Python代码: x = 1; total = 0; while x <= 2000000: y = 1; z = 0; while x >= y:
x = 1;
total = 0;
while x <= 2000000:
y = 1;
z = 0;
while x >= y:
if x % y == 0:
z += 1;
y += 1;
if z == 2:
total += x
x += 1;
print total;
x=1;
总数=0;
当x=y时:
如果x%y==0:
z+=1;
y+=1;
如果z==2:
总数+=x
x+=1;
打印总数;
很明显,这个帐篷里的长杆首先在计算素数列表。对于这种人为的情况,你可以得到其他人的列表(比如,一个),练习一下,然后在几秒钟内把数字加起来
但在我看来,这是不道德的。在这种情况下,如SO回答中所述,尝试atkin筛。如评论中所述,实施埃拉托斯烯筛将是一个更好的选择。它占用了
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)
max=2000000#我们只需要检查前200万个数字
数字=[]
总和=0
对于范围(2,max)中的i:#0和1不是素数
数字。附加(i)#填写我们的空白列表
对于范围内的p(2,最大值):
如果数字[p-2]!=-1:#如果p(我们的数组保持在2,而不是0)不是-1
#它是素数,所以把它加到我们的和中
总和+=数字[p-2]
#现在,我们需要将p的每一个倍数标记为复合,从2p开始
c=2*p
当c
这里唯一令人困惑的部分可能是我为什么使用
数字[p-2]
。这是因为我跳过了0和1,这意味着2在索引0处。换句话说,所有的东西都被2个索引移到一边。为了找到一个素数,而不是将所有的数字循环到素数,只需从2循环到数字的根,如果有匹配项,你知道它不是素数。这将使您的代码在O(n*sqrt(n))
中运行,而不是O(n^2)
您可能还需要研究更高效的素数生成算法,如、或