相比之下,超出了最大递归深度

时间:2013-11-17 17:47:24

标签: python recursion combinations factorial

我写了这段代码来计算组合数:

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:比较超出最大递归深度

6 个答案:

答案 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)

您的递归深度超出限制。

  1. 递归不是用Python做事的最惯用的方法,因为它没有tail recursion优化,因此使用递归作为迭代的替代是不切实际的(即使在你的例如,函数不是尾递归的,无论如何都不会有帮助。基本上,这意味着如果您希望输入量很大,那么您不应该将它用于复杂度大于线性的事物。

  2. 如果您的平台支持更高限制,则可以将限制设置为更高:

    sys.setrecursionlimit(some_number) sys.setrecursionlimit(some_number)

    此函数设置Python解释器堆栈的最大深度以限制。此限制可防止无限递归导致C堆栈溢出并导致Python崩溃。最高可能的限制取决于平台。当用户具有需要深度递归的程序和支持更高限制的平台时,用户可能需要将限制设置得更高。这应该小心,因为过高的限制可能导致崩溃。

  3. 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