我是自学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;
为什么你必须在里面调用这个函数?
提前谢谢!
答案 0 :(得分:2)
你问:“为什么你必须在里面调用这个功能?”嗯,严格来说,你没有。
Fibonacci sequence是此数学递归定义的数字序列:
原始函数确实计算了这个序列,尽管效率很低。如果Index
为0,则返回0;如果它是1,则返回1.否则返回GetFibNumber(Index - 1) + GetFibNumber(Index - 2)
,这正是数学定义所在。对于序列的每个元素,必须在序列中添加前两个术语。
您的代码只返回Index - 1 + Index - 2
,这将给出不同的数字序列。比较:
但除此之外,你并不需要一个递归函数来计算这个数学递归。您只需要一个简单的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
因为,如果你从未在函数中调用函数,它就永远不会更深入。从这个和其他答案应该清楚它为什么不正确。