我正在尝试使用递归
构建评分矩阵 for i in range(1, len(str1))
for j in range(1, len(str))
#do something
我的代码:
def matrix_bulid(index_1, index_2):
print(index_1, index_2)
if index_1 == len(first_dna) and index_2 == len(second_dna):
return
elif index_2 == len(second_dna):
return matrix_bulid(index_1 + 1, 1)
else:
#do something
matrix_bulid(index_1, index_2 + 1)
但是在非常长的字符串中,我得到最大深度错误的东西。 有没有人知道怎么做?
答案 0 :(得分:2)
如果你的目标是将嵌套的for循环变成一个简单的递归函数,那么你已经成功完成了。有一些错误(错误的缩进,在第二个递归情况下没有返回任何内容,...),但基本结构是健全的。
不幸的是,递归函数受到堆栈深度的限制。有些语言有尾调用消除,这意味着尾递归函数不受限制。而你的实现是尾递归的。但是Python(故意)没有这个功能,所以这并不重要;你仍然只能处理长达sys.getrecursionlimit()+1
的字符串。
如果你的字符串是有界的,但是对于默认的递归限制(在CPython中为1000)有点太大,你可以使用sys.setrecursionlimit
将其设置得更高。
在Python中也有模拟尾部调用消除的技巧,我将在下面讨论。但即使有最好的技巧,你的递归代码仍然比你的嵌套循环更长,更不明显,更少Pythonic,并且速度慢。
如果你正在为家庭作业做这件事,你可能已经完成了。除非您可以选择编程语言,否则您将需要选择具有尾调用消除功能的语言。如果您正在为真正的代码执行此操作,那么您应该坚持使用原始的嵌套循环 - 代码更简单,运行速度更快,并且没有堆栈限制,无需任何麻烦或复杂。
在CPython中实现尾调用优化的最有效方法是将编译函数的字节码修改为here。但这也是最黑客的方式,它只适用于有限的情况。
最简单的方法是修改函数以返回一个返回值而不是值的函数,然后使用trampoline将评估链接在一起(至少有两篇博客文章显示了这种技术,{{ 3}}和here)。但是,虽然这是最简单的实现,但它需要通过实际的递归函数进行更改,这会使它们更复杂,更不易读。
最好的权衡可能是使用在每个递归步骤中间插入蹦床的装饰器,因此您不需要显式延迟函数调用,如here所示。如果你有相互递归的函数,这可能会有点棘手,但很难弄清楚。而且实现很容易理解。它并不比字节码hackery慢得多。