我几天前才开始编程,并试图解决涉及大量素数的问题。这是我提出的方法,但是大数字很慢:
import time
import math
t0=time.clock()
a=100000
##preprimes is the list of primes up to sqrt(a) that will be
##divided into the larger list lista
preprimes=[]
lista= list(range(1,a))
prelista= list(range(1,round(math.sqrt(a))))
def predivisors(a):
x=a-1
suma=0
while (x>0):
if a%x==0:
suma=suma+x
x=x-1
if suma==1:
preprimes.append(a)
else:
x=x-1
for x in prelista:
predivisors(x)
for n in preprimes:
for num in lista:
if num%n==0:
lista.remove(num)
print(sum(lista)+sum(preprimes)-1 )
print(time.clock()-t0, ' seconds')
此方法需要81秒才能返回高达10万的素数之和。我在网上找到的以下方法在同一任务中花费了0.38秒:
import math
import time
t0=time.clock()
n=100000
def getPrimes(n):
"""returns set of all primes below n"""
non_primes = [j for j in range(4, n, 2)] # 2 covers all even numbers
for i in range(3, n, 2):
non_primes.extend([j for j in range(i*2, n, i)])
return set([i for i in range(2, n)]) - set(non_primes)
def getCircularPrimes(n):
primes = getPrimes(n)
is_circ = []
for prime in primes:
prime_str = str(prime)
iter_count = len(prime_str) - 1
rotated_num = []
while iter_count > 0:
prime_str = prime_str[1:] + prime_str[:1]
rotated_num.append(int(prime_str))
iter_count -= 1
if primes >= set(rotated_num):
is_circ.append(prime)
return len(is_circ)
print(sum(getPrimes(n)))
##print(sorted(getPrimes(n)))
print('process took ',time.clock()-t0,'seconds')
为什么第二种方法比我的快得多?哪些因素决定了流程需要多长时间?
答案 0 :(得分:0)
在您的方法中,您可以根据n
评估另一大数字列表中的n
个数字列表。
这样做,您就会执行大量作业
for n in preprimes:
for num in lista:
if num%n==0:
lista.remove(num)
我相信这会导致O(n^2)
范围内某处的时间复杂度
在线方法中,我认为它更接近O(n)
O(n)
和O(n^2)
之间的运行时差异随着输入n
的增长而急剧上升。