【发布时间】:2014-09-14 03:03:48
【问题描述】:
我为 Project Euler Problem 35写了一些代码:
#Project Euler: Problem 35
import time
start = time.time()
def sieve_erat(n):
'''creates list of all primes < n'''
x = range(2,n)
b = 0
while x[b] < int(n ** 0.5) + 1:
x = filter(lambda y: y % x[b] != 0 or y == x[b], x)
b += 1
else:
return x
def circularPrimes(n):
'''returns # of circular primes below n'''
count = 0
primes = sieve_erat(n)
b = set(primes)
for prime in primes:
inc = 0
a = str(prime)
while inc < len(a):
if int(a) not in b:
break
a = a[-1] + a[0:len(a) - 1]
inc += 1
else:
count += 1
else:
return count
print circularPrimes(1000000)
elapsed = (time.time() - start)
print "Found in %s seconds" % elapsed
我想知道为什么当我在circularPrimes 函数中设置b = set(primes) 时,这段代码(上面)运行得这么快。此代码的运行时间约为 8 秒。最初,我没有设置b = set(primes),而我的circularPrimes 函数是这样的:
def circularPrimes(n):
'''returns # of circular primes below n'''
count = 0
primes = sieve_erat(n)
for prime in primes:
inc = 0
a = str(prime)
while inc < len(a):
if int(a) not in primes:
break
a = a[-1] + a[0:len(a) - 1]
inc += 1
else:
count += 1
else:
return count
我的初始代码(没有b = set(primes))运行了很长时间,以至于我没有等待它完成。我很好奇为什么在两段代码之间的运行时间方面存在如此大的差异,因为我不相信primes 会有任何重复项会使迭代花费更长的时间通过set(primes)。也许我对 set() 的想法是错误的。欢迎任何帮助。
【问题讨论】:
-
检查
contains是集合中的常数时间,而列表中最坏情况的线性时间,这是我假设您从函数sieve_erat返回的时间。 -
顺便说一句,您可以利用素数列表已排序(
sieve_erat生成它)这一事实来加快速度。
标签: python performance set