斐波纳契数,为什么这种反复出现的功能有效?

时间:2010-11-03 23:53:00

标签: c++ numbers fibonacci

我正在阅读一本编程书,其中一个例子是关于斐波纳契数,以及一个重复函数如何找到第n个的斐波纳契数。

代码如下所示:

Int fib (int n)
{
If (n<3)
Return (1);
Else
Return (fib(n-1))+(fib(n-2))
}

现在这不完全正确,因为我正在通过手机输入并且我已经了解代码是如何工作的,它会调用自身直到它返回1,然后它会将返回值相加,直到您拥有正确的斐波那契数字对于序列中的位置。

所以我不需要代码的帮助。我需要帮助的是理解为什么这有效。添加所有回报如何给出正确答案?

请有人解释为什么这有效。谢谢。这让我很生气。

9 个答案:

答案 0 :(得分:12)

递归是这样的:

  1. 孩子无法入睡,所以她 妈妈告诉她一个关于a的故事 小青蛙,
  2. 谁也睡不着,所以青蛙的 妈妈告诉她一个关于a的故事 小熊,
  3. 谁也睡不着,所以熊的 妈妈告诉她一个关于a的故事 小鼬...
  4. 谁睡着了。
  5. ..小熊睡着了;
  6. ......小青蛙睡着了;
  7. ......孩子睡着了。
  8. source

答案 1 :(得分:8)

我建议理解递归是如何工作的。基本上,fib函数使用较小的参数执行自身,直到参数变为2,然后它才返回1.

fib(1) = 1
fib(2) = 1
fib(3) = fib(2) + fib(1) = 1 + 1 = 2
fib(4) = fib(3) [ fib(2) + fib(1) = 1 + 1 = 2 ] + fib(2) = 2 + 1
...

了解其工作原理的一种方法是逐步在调试器中运行它。

答案 2 :(得分:4)

Fibonacci数被定义为前两个Fibonacci数的总和。这给出了以下内容:

1 1 2 3 5 8 13 ...

因此,对于第3个数字(1 1 2 ),您将获得找到前一个数字的结果 - 即第二个数字(1 1 2)并将其添加到前一个数字 - 即第一个( 1 1 2)数字。

您还必须了解程序需要先计算前两个数字的值才能计算出您想知道的数字。因此,它一直在调用自己 - 使用相同的方法 - 直到它计算了所有内容。

答案 3 :(得分:4)

这是Fibonacci数字的定义。

第n个斐波那契数返回第(n-1)和第(n-2)个斐波那契数的总和。

因此我们可以通过归纳推理证明,如果fib(n-1)和fib(n-2)给出有效的(n-1)-th和(n-2)-th Fibonacci数,fib(n )= fib(n-1)+ fib(n-2)将是有效的第n个斐波纳契数。

基本步骤是fib(1)和fib(2)是正确的(即fib(1)= fib(2)= 1)......

答案 4 :(得分:3)

理解递归的技巧是理解堆栈。

我在名为main的函数的第2行,我的所有局部变量都存储在我的堆栈框架中:

+------------------+
| main() variables | The stack frame
+------------------+

然后我调用fib(3),因此计算机将当前位置(EIP)推送到堆栈,然后为fib创建一个新的堆栈帧并添加它。我只能访问顶部堆栈框架:

+------------------+
| fib()  n = 5     | Top of stack (current frame)
+------------------+
| EIP: main @ 2,1  |
+------------------+
| main() variables | Bottom of stack
+------------------+

fib的第4行,它再次调用fib,因此同样会再次发生:

+------------------+
| fib()    n = 4   | Top of stack
+------------------+
| EIP: fib @ 4,1   |
+------------------+
| fib()    n = 5   |
+------------------+
| EIP: main @ 2,1  |
+------------------+
| main() variables | Bottom of stack
+------------------+

它会一次又一次地执行此操作,因为函数是递归调用的。堆栈增长直到某些东西返回,此时,在fib的第2行,它返回1.这会弹出顶部堆栈帧并丢弃它,然后将执行返回到保存的执行指针,程序继续执行离开了

+------------------+
| fib()    n = 3   | Top of stack
+------------------+
    ... etc ...
+------------------+
| EIP: main @ 2,1  |
+------------------+
| main() variables | Bottom of stack
+------------------+

最终你回到了调用函数中(或者当它变得太大时你会得到一个堆栈溢出)。要记住的关键是每次调用函数时,它都会获得一个包含所有局部变量的新堆栈框架,并保存您之前的位置。这是递归。

主要问题是,在教授人们递归时,每个人总是使用Fibonacci序列,这意味着在一行上有两个递归函数调用。这是不必要的混淆,因为我相信你会同意的!

答案 5 :(得分:2)

斐波那契数被定义为前两个斐波纳契数的总和。它们各自被定义为前两个斐波纳契数的总和。 Etcetera等等,直到你达到1.理解?任何随机的斐波那契数都可以定义为两个斐波那契数的总和;那些可以递归地定义为两个斐波那契数的总和等。也就是说,斐波纳契数的定义从根本上是递归的;也就是说,它的定义涉及它所定义的内容。

这些东西可能很棘手,但它对理解递归和计算机科学非常重要。继续努力;它最终会点击。

答案 6 :(得分:1)

它被称为recursion

答案 7 :(得分:1)

本视频教程可以让您更好地了解Fibonacci递归的工作原理

[link] http://www.schooltrainer.com/study-material/computer-science/stepping-through-recursive-fibonacci-function.html

答案 8 :(得分:0)

根据定义,斐波纳契数是该系列中前两个数字的总和(前两个数字为0和1)。

因此,当您在一个位置获得斐波纳契数时,您可以将其重新写为前两个斐波纳契数的总和。

使用递归,你会经历这个过程,直到“先前的两个斐波那契数”为1和1(在这个算法的情况下),然后继续将这些数字加在一起“备份”递归,直到你得到回到序列中的原始位置。