比较超过最大递归深度
Posted
技术标签:
【中文标题】比较超过最大递归深度【英文标题】:maximum recursion depth exceeded in comparison 【发布时间】:2013-11-30 18:58:45 【问题描述】:我写了这段代码来计算组合的数量:
def fact(n):
return 1 if(n == 1) else n * fact(n - 1)
def combinations(n,k):
return fact(n)/((fact(n - k) * fact(k)))
while(True):
print(combinations(int(input()), int(input())))
阶乘函数似乎工作正常。但是,当我尝试查找两个数字的组合时,为什么它会给我一个超出比较错误的最大递归深度呢?阶乘函数是否有问题,因为这似乎是错误的来源?
这是我得到的错误:
builtins.RuntimeError:比较中超出了最大递归深度
【问题讨论】:
math.factorial
有什么问题吗?
scipy.misc.comb
有什么问题?
【参考方案1】:
对于像阶乘这样的简单函数,您应该尽量避免递归。递归确实很强大,但有时会无缘无故地被过度使用。
下面是阶乘函数迭代版本的代码:
def fact(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
请注意 Maxime 在上一个答案中所说的,这正是您遇到的问题:您的函数没有考虑 0 的阶乘。
【讨论】:
【参考方案2】:尝试替换:
def fact(n):
return 1 if(n == 1) else n * fact(n - 1)
到:
def fact(n):
return 1 if(n <= 1) else n * fact(n - 1)
因为如果您传递 2 个相同的数字,您将尝试计算 fact(0)
(这将调用 fact(-1)
和 fact(-2)
等,直到最大递归深度错误)。
【讨论】:
【参考方案3】:python 3.x 及以后的版本默认递归限制为 2000 次,如果你一次又一次地调用同一个函数超过 2000 次,你会得到最大递归深度错误。理想的方法是编写没有递归的逻辑。但如果您仍然坚持递归,请通过以下方式更改默认递归限制:
导入系统
sys.setrecursionlimit(10000)# 设置递归限制为10000。
但在某些情况下,上述内容可能无法满足您的所有需求。
【讨论】:
这里我们遇到了递归比较次数的问题。该限制远低于最大递归深度。【参考方案4】:你的递归深度超出了限制。
递归不是 Python 中最惯用的做事方式,因为它没有 tail recursion 优化,因此使用递归代替迭代是不切实际的(即使在您的示例中函数是不是尾递归,无论如何这都无济于事)。基本上,这意味着如果您希望输入很大,则不应将其用于复杂性大于线性的事物。
如果你的平台支持更高的限制,你可以将限制设置得更高:
sys.setrecursionlimit(some_number)
sys.setrecursionlimit(some_number)
此函数将 Python 解释器堆栈的最大深度设置为限制。此限制可防止无限递归导致 C 堆栈溢出和 Python 崩溃。可能的最高限制取决于平台。当用户有一个需要深度递归的程序和一个支持更高限制的平台时,她可能需要将限制设置得更高。这应该小心完成,因为过高的限制会导致崩溃。
参考:Python recursive function error: “maximum recursion depth exceeded”Python max recursion , question about sys.setrecursionlimit()
【讨论】:
【参考方案5】:sys.setrecursionlimit(some_number)
【讨论】:
【参考方案6】:这样的东西效果很好:
def factorial_by_recursion(max_number, current_number, somme):
if current_number < max_number:
somme += current_number
return factorial_by_recursion(max_number, current_number + 1, somme)
else:
return somme
【讨论】:
以上是关于比较超过最大递归深度的主要内容,如果未能解决你的问题,请参考以下文章
Binary Search RecursionError:比较超过最大递归深度