【问题标题】:why maximum recursion limit error is caused when code(1) is executed and no error when code(2) is executed为什么执行code(1)时出现最大递归限制错误而执行code(2)时没有错误
【发布时间】:2018-10-30 20:36:49
【问题描述】:

这里是使用递归函数的斐波那契数列的 2 个 Python 代码。我想知道这些代码之间的区别以及为什么 code(1) 不工作,而 code(2) 工作没有任何错误?

这不起作用并显示最大递归限制错误:

def f(n):
   return f(n-1) + f(n-2)

n=8
f(n)

这是可行的:

def f(n):
   if n == 0:
      return 0
   if n == 1:
      return 1
   else:
      return f(n-1) + f(n-2)

f(4)

【问题讨论】:

  • 因为你的递归没有中断条件,它递归到无穷大
  • 这样的问题很容易通过自己调试代码来回答 - 在此处阅读:python debugging tips
  • 查看这个可爱的debug 博客寻求帮助。

标签: python recursion fibonacci


【解决方案1】:

您的第一个代码无法停止。它没有 n == 0 或 n == 1 的基本情况,因此它将以负数无限向下。

如果添加:

  if n <= 1:
      return 0

你是金子。 (尽管它是斐波那契的一个非常低效的实现)。

为什么它效率低,因为每个子树都被计算了很多次。 f(8) 调用 f(7) 和 f(6),但 f(7) 也调用 f(6),所以你得到一个指数递归树。您的运行时间将为 O(2^n)。这真的很糟糕,通常即使 n 低至 50,您也无法计算 fib。

如果你包含记忆,你可以做得更好:

from functools import lru_cache

@lru_cache(maxsize=None)
def fib2(n):
    if n <= 1:
        return n
    else:
        return fib2(n-1) + fib2(n-2)

这将记住您之前是否调用过 f(n) 并返回您上次所做的答案。现在的问题是你需要记住以前的被叫号码,所以当你的运行时间减少到 O(n) 时,你的空间需求现在也是 O(n)。

你可以再次改进这一点,放弃递归函数,然后继续

def fib3(n):
if n == 0:
    return 0
f1 = 0
f2 = 1

for i in range(n-1):
    f1,f2 = f2, f1+f2
return f2

这样更好,因为您在任何时候都只记住两个数字。

【讨论】:

  • 是的,就在几秒钟前,我找到了原因,但非常感谢您的时间和耐心。
猜你喜欢
  • 2013-04-28
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
相关资源
最近更新 更多