我写了这段代码来计算组合数:
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:比较超出最大递归深度
答案 0 :(得分:3)
尝试替换:
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)
等,直到最大递归深度误差。)
答案 1 :(得分:3)
你应该尽量避免递归这样一个简单的函数作为数字的阶乘。递归真的很强大,但有时它无缘无故被过度使用。
以下是阶乘函数的迭代版本的代码:
def fact(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
请注意Maxime在上一个答案中所说的,这正是您遇到的问题:您的函数没有考虑因子0。
答案 2 :(得分:3)
python 3.x版本以后的默认递归限制仅为2000,如果再次多次调用同一函数超过2000次,则会出现最大递归深度错误。理想的方法是编写一个没有递归的逻辑。但是如果仍然坚持递归,请通过以下方式更改默认递归限制:
导入sys
sys.setrecursionlimit(10000)#它将递归限制设置为10000。
但在某些情况下,上述内容可能无法满足您的所有需求。
答案 3 :(得分:1)
您的递归深度超出限制。
递归不是用Python做事的最惯用的方法,因为它没有tail recursion优化,因此使用递归作为迭代的替代是不切实际的(即使在你的例如,函数不是尾递归的,无论如何都不会有帮助。基本上,这意味着如果您希望输入量很大,那么您不应该将它用于复杂度大于线性的事物。
如果您的平台支持更高限制,则可以将限制设置为更高:
sys.setrecursionlimit(some_number)
sys.setrecursionlimit(some_number)
此函数设置Python解释器堆栈的最大深度以限制。此限制可防止无限递归导致C堆栈溢出并导致Python崩溃。最高可能的限制取决于平台。当用户具有需要深度递归的程序和支持更高限制的平台时,用户可能需要将限制设置得更高。这应该小心,因为过高的限制可能导致崩溃。
REF:
Python recursive function error: “maximum recursion depth exceeded”
Python max recursion , question about sys.setrecursionlimit()
答案 4 :(得分:0)
sys.setrecursionlimit(some_number)
答案 5 :(得分:0)
类似的东西很好用
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