我一直很好奇这件事。对于人来说,创建一个非尾递归函数以获得复杂的东西真的非常容易和优雅,但速度非常慢并且很容易达到Python递归的极限:
def moves_three(n, ini=0, med=1, des=2):
'''give a int -> return a list '''
if n == 1:
return ((ini,des),)
return moves_three(n-1, ini=ini, med=des, des=med) + \
((ini, des),) + \
moves_three(n-1, ini=med, med=ini, des=des)
if __name__ == '__main__':
moves_three(100) # may be after several hours you can see the result.
len(moves_three(10000))
那么,如何将moves_three
更改为尾递归一个或一个循环(更好)?更重要的是,有没有论文可以谈论这个?感谢。
答案 0 :(得分:2)
即使使用迭代形式,这也不会更快。问题不在于递归限制;你仍然比递归限制低一个数量级。问题是输出的大小为O(2^n)
。对于n=100
,你必须建立一个大约千亿亿元素的元组。你如何建造它并不重要;你永远不会完成。
如果你想将它转换为迭代,可以通过使用显式堆栈而不是调用堆栈来管理状态来完成:
def moves_three(n, a=0, b=1, c=2):
first_entry = True
stack = [(first_entry, n, a, b, c)]
output = []
while stack:
first_entry, n1, a1, b1, c1 = stack.pop()
if n1 == 1:
output.append((a1, c1))
elif first_entry:
stack.append((False, n1, a1, b1, c1))
stack.append((True, n1-1, a1, c1, b1))
else:
output.append((a1, c1))
stack.append((True, n1-1, b1, a1, c1))
return tuple(output)
令人困惑,不是吗?堆栈上的元组(True, n, a, b, c)
表示使用参数n, a, b, c
输入函数调用。元组(False, n, a, b, c)
表示在(True, n, a, b, c)
结束后返回moves_three(n-1, a, c, b)
来电。