简体   繁体   English

尾递归Fibonacci

[英]Tail Recursion Fibonacci

如何在O(n)中没有运行循环的情况下实现递归Fibonacci函数?

Typically I'd be against posting an answer to a homework question like this, but everything posted so far seems to be overcomplicating things. 通常情况下,我反对在这样的家庭作业问题上发布答案,但到目前为止发布的所有内容似乎都过于复杂。 As said in the comments above, you should just use recursion to solve the problem like you would do iteratively. 如上面的评论中所述,您应该使用递归来解决问题,就像迭代一样。

Here's the iterative solution: 这是迭代解决方案:

def fib(n):
  a, b = 0, 1
  while n > 0:
    a, b = b, a+b
    n -= 1
  return a

Here's an equivalent recursive solution: 这是一个等效的递归解决方案:

def fib(n):
  def fib_help(a, b, n):
    return fib_help(b, a+b, n-1) if n > 0 else a
  return fib_help(0, 1, n)

Note that in both cases we actually compute up to F n+1 , but return F n as the result. 请注意,在这两种情况下,我们实际计算最多F n + 1 ,但返回F n作为结果。 This fits nicely with the "hint" you were given. 这非常适合你给出的“提示”。

I hope that you'll take the time to compare the two solutions and convince yourself that they're equivalent. 我希望你花时间比较这两种解决方案并说服自己相同。 Understanding how to transform an iterative solution to an equivalent recursive one (or vice versa) is a good skill to develop. 了解如何将迭代解决方案转换为等效的递归解决方案(反之亦然)是一项很好的开发技巧。

Scala code for finding nth Fibonacci Number. 用于查找第n个Fibonacci数的Scala代码。 For more information on Tail Recursion http://nerds.logdown.com/posts/1406258-n-th-fibonacci-number 有关尾递归的更多信息,请访问http://nerds.logdown.com/posts/1406258-n-th-fibonacci-number

object Main {
     def main(args: Array[String]) {
        println(fib(9));
        println(fib(8));
        println(fib(7));
        println(fib(6));
        println(fib(5));
        println(fib(4));
        println(fib(3));
        println(fib(2));
        println(fib(1));
        println(fib(0));
      }
      def fib(n: Int): Int = {
        def fib(n: Int, p :Int, c: Int): Int ={
          if (n == 0) return -1; // undefined
          if (n == 1) return p;
          fib(n-1, c, p + c)
        }
        fib(n, 0, 1);
      }
    }

To solve this in linear time, you must use a dynamic programming technique known as memoization. 要在线性时间内解决此问题,必须使用称为memoization的动态编程技术。

The algorithm for Fibonacci in pseudo-code, using memoization, looks like this: 伪代码中使用memoization的Fibonacci算法如下所示:

memoryMap[n]

func fib(int n)
    if (n is in memoryMap) then
        return memoryMap[n]
    if (n <= 1) then
        memoryMap[n] = n
    else
        memoryMap[n] = fib(n-1) + fib(n-2)

    return memoryMap[n]

To explain, you after each call to fib(x) you be storing the result in a memory map. 为了解释,在每次调用fib(x)之后,您将结果存储在存储器映射中。 For each subsequent call, all lookups to fib(x) will be free: that is, looking up the result in the memory costs only O(1) time. 对于每个后续调用,对fib(x)的所有查找都是空闲的:也就是说,在内存中查找结果仅花费O(1)时间。

In case someone is looking for a JavaScript solution: 如果有人正在寻找JavaScript解决方案:

function _fib(n, left, right) {
  switch (n) {
    case 0: return 0
    case 1: return right
    default: return _fib(n - 1, right, left + right)
  }
}

function fib(n) {
  return _fib(n, 0, 1)
}

That runs in O(n) time and O(1) space with tail call optimization. 它在O(n)时间和O(1)空间中运行,具有尾调用优化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM