我正在尝试解决Project Euler中的10个问题。它包括找到200万以下所有素数的总和。我根据Eratosthenes的Sieve编写了以下代码。
import time
t0 = time.time()
n=200000
liste=list(range(2,n))
k=2
s=2
while k <=n:
liste=list(set(liste)-set(range(k,n,k)))
if liste!=[]:
k=min(liste)
s+=k
else:
break
print(s)
t1 = time.time()
total = t1-t0
print(total)
我测试了上面的代码n = 200000,但是对于n = 2000000来说它太慢了。我非常感谢能够帮助改进这个计划。
答案 0 :(得分:0)
为了找到低于200000的素数之和,下面的代码(使用eratosthenes的筛子)工作得更快,你的代码需要将近55秒,而下面的代码只需0.8秒即可执行!
import time
t0 = time.time()
n = 200000
sieve = [True] * (n + 1)
for i in range(2, n + 1) :
if sieve[i] :
for mult in range(i + i, n + 1, i) :
sieve[mult] = False
s=0
for i in range(2,n + 1):
if sieve[i] :
s+=i
print(s)
t1 = time.time()
total = t1-t0
print(total)
答案 1 :(得分:0)
始终尝试在多个范围内衡量代码的empirical complexity。
您的代码很慢,因为您找到了设置差异,并且始终在set和list之间进行转换。您应该始终使用一个集合,并使用
更新它 sete.difference_update(range(p*p,n,p*2))
要查找min元素,您只需在集合上调用min(sete)
,无需转换列表。
由于对min元素的搜索效率低,所得到的代码的整体复杂性将接近 n ^ 1.5 ,这不是太亮,但也不是太可怕。特别是,它在ideone.com上以4.9秒完成,找到2000000以下的素数的总和,以及400000的0.5秒(首先仅使用赔率进行额外优化)。