几周前我在python中编写了erathostenes算法,看起来如下:
def erathostenes(n):
A = range(2,n+1)
B = []
i = 0
while A[i] < math.sqrt(n):
B.append(A[i])
j = i
aux = A[i]
while j < len(A):
if A[j]%aux == 0:
A[j] = 0
j += aux
i += 1
while A[i] == 0:
i += 1
for i in range(len(A)):
if A[i] != 0:
B.append(A[i])
i += 1
return B
稍微思考一下(编程中我是菜鸟)我刚刚在我的算法中做了一些修改,现在看起来像:
def erathostenes(n):
A = range(2,n + 1)
B = []
i = 0
raiz = math.sqrt(n)
lenA = len(A)
rangeLenA = range(lenA)
while A[i] < raiz:
B.append(A[i])
j = i
aux = A[i]
while j < lenA:
A[j] = 0
j += aux
i += 1
while A[i] == 0:
i += 1
for i in rangeLenA:
if A[i] != 0:
B.append(A[i])
i += 1
return B
如果我执行n = 10.000.000的算法,第一个代码中的执行时间约为7秒,第二个代码的执行时间约为4秒。
关于我算法中的一些更优化的想法?谢谢!
答案 0 :(得分:4)
i += 1
在最后一个循环中很有趣。
考虑更换
for i in rangeLenA:
带
for i in xrange(LenA)
你避免生成一个你不需要的巨大列表。
编辑:
还要考虑这个:
for j in xrange(i,lenA,aux):
而不是:
while j < lenA:
修复错误
while A[i] <= raiz:
按照fryday的建议。
答案 1 :(得分:2)
您的代码中存在错误。变化
while A[i] < raiz:
在
while A[i] <= raiz:
当N为方形时,您可以发现错误。
对于opimization,使用 xrange rangeLenA 而不是范围。
答案 2 :(得分:2)
尝试制作非循环版本只是为了好玩。它出来是这样的:
def erathostenes(n):
def helper_function(num_lst, acc):
if not num_lst:
return acc
if len(num_lst) == 1:
acc.append(num_lst[0])
return acc
num = num_lst.pop(0)
multiples = ([x for x in range(num + 1, num_lst[-1] + 1)
if x % num == 0])
remains = ([x for x in num_lst if x not in multiples])
acc.append(num)
return helper_function(remains, acc )
return helper_function(range(2, n + 1), [])
当我运行计时时,为了我的版本(!!)获得了826个用于邮件的时间(1000)和26毫秒。让我感到惊讶的是它太慢了。
函数式编程它更有趣,但在Python中看起来不适合这个问题(我的猜测是它在更多功能语言中会更快)。
所以我尝试了一个命令式版本。它看起来像这样:
def erathostenes_imperative(n):
limit = int(math.sqrt(n))
def helper_function(flags, size):
for i in range(2,limit):
if flags[i] == True:
j = 2*i
while j < size:
if j % i == 0:
flags[j] = False
j = j + i
return [x for x in range(2, n + 1) if flags[x]]
return helper_function([True]*(n + 1), n)
我所做的是将整数列表更改为True / False标志列表。直观地说,看起来迭代更快,对吧?
我的结果是,对于erathostenes_imperative(100000)为831ms,而您的版本为1.45。
令人遗憾的是,命令式写作速度更快。代码看起来很混乱所有的fors,whiles,我和j的
答案 3 :(得分:1)
尝试阿特金筛选。它是类似的,但它是对Eratosthenes筛子的修改,它过滤掉了所有2,3,5的倍数,以及其他一些优化。您可能还想尝试找到一个工具,告诉您每个操作的运行时间,并使用更长的运行时间修改操作。
但是,由于您不熟悉编程,因此最好是实现其他算法,或者进行其他编程练习来改进。