使用Fibonacci系列的递归函数

时间:2013-12-17 12:55:21

标签: c++ recursion fibonacci

我是自学C ++来自 Sams教你自己C ++每天一小时和第150页,作者讨论了使用Fibonacci系列的递归函数。

他使用以下代码:

#include <iostream>
using namespace std;

int GetFibNumber(int FibIndex)
{
    if(FibIndex < 2 )
        return FibIndex;
    else
        return GetFibNumber(FibIndex - 1) + GetFibNumber(FibIndex - 2);
}

int main()
{
    cout << " Enter 0 based index of desired Fibonacci Number: ";
    int Index = 0;
    cin >> Index;

    cout << " Fibonacci number is: " << GetFibNumber(Index) << endl;

    return 0;

}

之间的区别

返回GetFibNumber(FibIndex - 1)+ GetFibNumber(FibIndex - 2);

返回FibIndex - 1 + FibIndex - 2;

为什么你必须在里面调用这个函数?

提前谢谢!

5 个答案:

答案 0 :(得分:2)

你问:“为什么你必须在里面调用这个功能?”嗯,严格来说,你没有。

Fibonacci sequence是此数学递归定义的数字序列:

  • a 0 = 0
  • a 1 = 1
  • a n = a n-1 + a n-2

原始函数确实计算了这个序列,尽管效率很低。如果Index为0,则返回0;如果它是1,则返回1.否则返回GetFibNumber(Index - 1) + GetFibNumber(Index - 2),这正是数学定义所在。对于序列的每个元素,必须在序列中添加前两个术语。

您的代码只返回Index - 1 + Index - 2,这将给出不同的数字序列。比较:

  • Fibonacci:0,1,1,2,3,5,8,13,21,36 ......
  • 你的:0,1,1,3,5,7,9,11,13,17 ......

但除此之外,你并不需要一个递归函数来计算这个数学递归。您只需要一个简单的for循环:

int GetFibNumber(int FibIndex)
{

    if(FibIndex < 2 )
        return FibIndex;

    int a_n_2 = 0, a_n_1 = 1, a_n;

    for (i = 2; i < FibIndex; i++)
    {
        a_n = a_n_1 + a_n_2;
        a_n_2 = a_n_1;
        a_n_1 = a_n;
    }

    return a_n;
}

这种方法也会快得多。

代码递归技术在数学上是正确的。然而,它更慢,因为它不重用任何计算。它通过将递归重新加工回 1 来计算 n-1 。然后它计算 n-2 ,而不重用任何生成 n-1 的工作。如果你认为在递归的每一步都会发生这种重用不足的情况,你会看到running time grows exponentially for the recursive function.for循环的线性增长。


高级主题:有一种方法可以使递归版本运行得更快,并且知道您是否遇到最容易递归定义的编程问题,这一点非常重要。一旦你对C ++更加熟悉,请查看memoization。一个memoized递归Fibonacci给出线性最坏情况运行时和重复查找的恒定运行时间(假设备忘录查找本身是O(1))。

答案 1 :(得分:1)

使用不使用递归的版本不正确。它只会正确计算前几个Fiboonacci数。尝试使用这两个版本计算前10个Fibonacci数,您将看到自己两个版本计算两个不同的序列。

答案 2 :(得分:1)

函数GetFibNumber计算Fibonacci系列中的第N个数。如果您只是查看http://en.wikipedia.org/wiki/Fibonacci_number上的解释,可以通过在Fibinacci系列中添加Nth-1和Nth-2数来计算。而这正是函数所做的。你为函数提供了你想要计算的Fibonacci系列中的索引(比方说6;结果应该有8个)。

要计算Fibonacci系列中的第6个元素,您需要将第5个和第4个元素一起添加。所以你首先需要计算这些。这是递归步骤的地方。你可以让函数调用自己;但是不是再次使用值6作为参数再次调用它,而是使用5和4.这将再次导致相同的问题(您需要通过添加元素4和3来计算第5个元素)等等。

使用递归函数,您可以简单地重复使用代码一遍又一遍地执行相同的计算,直到达到您有计算答案的某个点(在这种情况下,如果N = 1或N = 0) ;这些案件将导致1)。

答案 3 :(得分:1)

我建议,既然你还在学习,那么递归编程(就像作者那样)和使用循环(while,for)。它很可能会向您展示如何构建此算法的答案。

提示1:你必须知道Fibonnaci序列是建立在两个初始值...

提示2:对于递归,您应该知道函数结果是如何存储的。这也将解释你的问题。

答案 4 :(得分:1)

它们不相同,它肯定不会计算纤维蛋白序列。递归可以被认为是一棵树,所以计算Fib(8)说,根据定义我们采用Fib(7)+ Fib(6)

        Fib(8)
        /    \
    Fib(7)   Fib(6)

反过来又要求计算Fib(6),Fib(5),Fib(4)如下:

                 Fib(8)
               /        \
          Fib(7)       Fib(6)
        /        \    /      \
     Fib(5)   Fib(6) Fib(5)  Fib(4)

等等。你正在做什么,会产生一个不同的深度1树:

    Fib(8)
    /    \
   7      6

因为,如果你从未在函数中调用函数,它就永远不会更深入。从这个和其他答案应该清楚它为什么不正确。