欧拉计划中的第十个问题:
我找到了这个片段:
sieve = [True] * 2000000 # Sieve is faster for 2M primes
def mark(sieve, x):
for i in xrange(x+x, len(sieve), x):
sieve[i] = False
for x in xrange(2, int(len(sieve) ** 0.5) + 1):
if sieve[x]: mark(sieve, x)
print sum(i for i in xrange(2, len(sieve)) if sieve[i])
已发布 here
运行 3 秒。
我写了这段代码:
def isprime(n):
for x in xrange(3, int(n**0.5)+1):
if n % x == 0:
return False
return True
sum=0;
for i in xrange(1,int(2e6),2):
if isprime(i):
sum += i
我不明白为什么我的代码(第二个)要慢得多?
最佳答案
您的算法正在分别检查从 2 到 N(其中 N=2000000)的每个数字的素数。
Snippet-1 使用大约 2200 年前发现的 sieve of Eratosthenes 算法。
它不会检查每个数字,但是:
因此该算法产生最多 N 的所有素数。
请注意,它不做任何除法,只做加法(甚至不做乘法,而且对于这么小的数字并不重要,但对于较大的数字可能很重要)。时间复杂度是
O(n loglogn)
而你的算法有一些接近 O(n^(3/2))
(或@Daniel Fischer 评论的 O(n^(3/2) / logn)
),假设除法成本与乘法相同。来自维基百科(上面链接)文章:
(在这种情况下使用
n = 2e6
)