我试图在Python 2.7上使用筛子获得所有素数的总和。但是当我运行程序时,我每次只能得到0。 我不知道为什么会这样。
import math,time
start=time.clock()
def primesieve(limit):
final=0
a=[True]*limit
a[0]=a[1]=False
for i,isprime in enumerate(a):
if isprime:
for n in xrange(i,limit,i):
a[n]=False
for i in xrange(limit):
if a[i]:
final=final+i
return final
print primesieve(2000000)
elapsed=time.clock()-start
print elapsed
答案 0 :(得分:2)
for n in xrange(i,limit,i):
a[n]=False
应该是:
for n in xrange(2*i,limit,i):
a[n]=False
或者,更有效率:
for n in xrange(i*i,limit, 2*i): #assuming you already cleared even numbers
a[n]=False
因为否则你最终将i
设置为非素数,当它实际上是素数时。
(筛子应将i
的所有倍数标记为非素数,但i
本身除外!)
请注意,您正在迭代所有数字,最多limit
,但您可以在到达sqrt(limit)
后安全停止:
import itertools as it
def primesieve(limit):
a = [True] * limit
a[0] = a[1] = False
sqrt_limit = int(limit**0.5) + 1
predicate = lambda x: x[0] <= sqrt_limit
for i, isprime in it.takewhile(predicate, enumerate(a)):
if isprime:
for n in xrange(i*i, limit, i):
a[n] = False
return sum(i for i,n in enumerate(a) if n)
takewhile
函数将在到达limit
的平方根后立即停止迭代。 i*i
不会出错,因为它总是小于limit
。
在我的机器上,它的速度是迭代所有数字的两倍。
答案 1 :(得分:2)
看看这个相关主题: Fastest way to list all primes below N 8 * 10 ^ 8以下的最快筛网是由@Robert William Hanks编码的rwh_prime1
'''Robert William Hanks 2010'''
def primes1(n):
""" Returns a list of primes < n """
sieve = [True] * (n/2)
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i/2]:
sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1)
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]