【问题标题】:What is going on with the "return fibonacci... " in this program?这个程序中的“返回斐波那契......”是怎么回事?
【发布时间】:2012-06-26 05:15:48
【问题描述】:

我无法理解return fibonacci( number-1 ) + fibonacci( number-2 ) 在以下程序中的作用:

import sys
def fibonacci( number ):
    if( number <= 2  ):
        return 1
    else:
        return fibonacci( number-1 ) + fibonacci( number-2 )

问题是我无法想象这条线是如何工作的:

return fibonacci( number-1 ) + fibonacci( number-2 )

“fibonacci(number-1)”和“fibonacci(number-2)”是否同时处理?还是“fibonacci(number-1)”是第一个被处理的,然后是第二个?

我只看到处理它们最终会返回“1”,所以我希望看到的最后一个结果是“1 + 1”=“2”

如果有人能详细解释其计算过程,我将不胜感激。

我认为这是一个非常新的问题,但我无法真正了解其过程。

【问题讨论】:

  • 简答:Python首先评估第一个,完成后,它会评估第二个调用。
  • 应该是if number &lt; 2:

标签: python recursion fibonacci


【解决方案1】:

我非常喜欢诺伦皇室的回答,但还是有点难以想象。所以,经过一番折腾:

...时间从左到右流动,稍作调整以防止一些重叠的边缘。不递归的叶子节点是橙色的。

【讨论】:

    【解决方案2】:

    一开始我在理解递归时遇到了一些困难,所以我将尝试通过该函数。

    现在假设你调用 fibonacci(4)

    由于数量大于 2 python 将转到此行:

    返回斐波那契(number-1)+斐波那契(number-2)

    所以它会开始评估和调用:

    斐波那契(3) #这是斐波那契(4 - 1)

    因为每次遇到函数调用它都必须运行它(可以这么说)。

    所以现在它会尝试做 fibonacci(3),因为它大于 2:

    它会再次进入这一行:

    返回斐波那契(number-1)+斐波那契(number-2)

    现在它用 3 调用它,所以当它到达 fibonacci(number-1) 时它会这样做:

    斐波那契(2) #这是斐波那契(3 - 1)

    由于数字等于 2,所以这个递归调用将返回 1。现在你必须记住/想象 python 知道 fibonacci(2) 的答案。

    所以现在它有了 fibonacci(2) 的答案,它将继续执行这一行:

    返回斐波那契(number-1)+斐波那契(number-2)

    具体如下:+ fibonacci(number-2)

    请记住,我们正站在斐波那契 (2) 中,所以这将执行斐波那契 (1),这将返回 1。

    所以现在当我们返回时,我们开始返回,也就是说,我们递归地退出函数。

    出了什么问题?当我们做斐波那契(4)时,我们需要知道斐波那契(3),斐波那契(2),斐波那契(1),现在我们知道了。

    所以当它递归到斐波那契(3)时,它需要知道斐波那契(2)和斐波那契(1)并且它知道,所以现在我们现在是斐波那契(3)。

    现在我们回到斐波那契(4),我们需要知道斐波那契(3)和斐波那契(2),我们都知道,所以它会返回什么,两者的总和。

    我希望很清楚,递归很难理解,但通过练习会变得更好。

    尝试通过调用来跟踪函数调用(用铅笔写下)您正在调用什么调用,以及从调用中获得的结果。

    请记住,在这种递归中,您在“寻找答案”的递归级别中下降,当您获得这些答案(返回)时,您会再次返回以给出未知值的答案。

    【讨论】:

    • 谢谢,你的帖子确实给了我图片。
    • 没问题,有什么问题就问吧!
    【解决方案3】:

    你为什么不做这样的事情:

    >>> def fibonacci(number):
    ...     if number < 2:
    ...         return number
    ...     print "Number is currently %d, getting fibonacci(%d)" % (number, number - 1)
    ...     minus_one = fibonacci(number-1)
    ...     print "Number is currently %d, just got fibonacci(%d), now getting fibonacci(%d)" % (number, number - 1, number - 2)
    ...     minus_two = fibonacci(number-2)
    ...     print "Number is currently %d, returning %d + %d" % (number, minus_one, minus_two)
    ...     return minus_one + minus_two
    

    这样当您致电fibonacci 时,您会得到如下信息:

    >>> fibonacci(4)
    Number is currently 4, getting fibonacci(3)
    Number is currently 3, getting fibonacci(2)
    Number is currently 2, getting fibonacci(1)
    Number is currently 2, just got fibonacci(1), now getting fibonacci(0)
    Number is currently 2, returning 1 + 0
    Number is currently 3, just got fibonacci(2), now getting fibonacci(1)
    Number is currently 3, returning 1 + 1
    Number is currently 4, just got fibonacci(3), now getting fibonacci(2)
    Number is currently 2, getting fibonacci(1)
    Number is currently 2, just got fibonacci(1), now getting fibonacci(0)
    Number is currently 2, returning 1 + 0
    Number is currently 4, returning 2 + 1
    3
    

    它仍然很复杂,但至少现在您可以看到该函数正在做什么来计算您的数字。

    【讨论】:

    • 对!!非常感谢这是我试图理解的。而且...问题是我不擅长调试或测试,对不起,如果我这样做,问题就不会发布。再次感谢!
    • OP,这是一种可视化您所怀疑的东西的好方法,很好的答案! +1
    • err... 对不起,'OP' 是什么意思?
    • "OP" = "Original Poster"(问题或答案)
    • @user1478598 抱歉,是的,OP 是指原始海报,我是指你 :)
    【解决方案4】:

    “fibonacci(number-1)”和“fibonacci(number-2)”是否同时处理?还是“fibonacci(number-1)”是第一个被处理的,然后是第二个?

    重要吗?


    发生的事情是该函数被调用了两次。一次是number 的值-1,一次是-2,用于传递给函数当前“实例”的number 的值。

    假设你打电话给fibonacci(3)。该行最终将是:

    return fibonacci(2) + fibonacci(1)
    

    【讨论】:

    • 然后首先评估fibonacci(2),其次评估fibonacci(1)
    • @MartijnPieters - 很公平,但要理解最终结果,这真的没关系。
    • @MartijnPieters - 在字里行间阅读。 OP 对递归以及在一行上对同一函数的两次调用如何工作感到困惑。我的观点是,该机制对于理解其工作原理并不重要。如果您更改评估顺序,您最终会得到相同的理解。
    • 我知道 :-) 但有可能他认为这些方法是并行执行的。
    • @MartijnPieters - 这仍然无关紧要,因为该行只会在两个(虚构的)“堆栈”都完成时评估......
    猜你喜欢
    • 2011-08-10
    • 2019-04-06
    • 1970-01-01
    • 2012-10-12
    • 2014-07-05
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多