Explanation of Recursion with Fibonacci Numbers
我找到了一个代码,它可以确定一个数字是否是斐波那契数。我希望有人能够更容易地分解它。
1 2 3 4 5 6 7 8 | def is_fibonacci?(i, current = 1, before = 0) return true if current == i || i == 0 return false if current > i is_fibonacci?(i, current + before, current) end is_fibonacci?(3) # => true is_fibonacci?(4) # => false |
我知道一个方法在递归中调用自己,并且需要有一个基本情况,但是我再次很难想象正在发生的事情。任何帮助将不胜感激。
可视化它的最简单方法是一次通过计算一个方法调用,假设我们想要评估 那么,由于
2
3
4
5
is_fibonacci?(8, 2, 1)
is_fibonacci?(8, 3, 2)
is_fibonacci?(8, 5, 3)
is_fibonacci?(8, 8, 5)
最后,
编辑:考虑这种递归的另一种方法是,您的
您可以检查调用跟踪 if
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | is_fibonacci?(10, current = 1, before = 0) is_fibonacci?(10, current = 1, before = 1) is_fibonacci?(10, current = 2, before = 1) is_fibonacci?(10, current = 3, before = 2) is_fibonacci?(10, current = 5, before = 3) is_fibonacci?(10, current = 8, before = 5) is_fibonacci?(10, current = 13, before = 8) is_fibonacci?(144, current = 1, before = 0) is_fibonacci?(144, current = 1, before = 1) is_fibonacci?(144, current = 2, before = 1) is_fibonacci?(144, current = 3, before = 2) is_fibonacci?(144, current = 5, before = 3) is_fibonacci?(144, current = 8, before = 5) is_fibonacci?(144, current = 13, before = 8) is_fibonacci?(144, current = 21, before = 13) is_fibonacci?(144, current = 34, before = 21) is_fibonacci?(144, current = 55, before = 34) is_fibonacci?(144, current = 89, before = 55) is_fibonacci?(144, current = 144, before = 89) 10 : false , 144 : true |
这是为前 10 个斐波那契数提供此输出的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | def fib(n) if n <= 0 then 1 else fib(n-1) + fib(n - 2) end end def is_fibonacci?(i, current = 1, before = 0, level=0) puts ("" * level) +" is_fibonacci?(#{i}, current = #{current}, before = #{before})" if current == i || i == 0 then return true elsif current > i then return false else is_fibonacci?(i, current + before, current, level+1) end end (0..10).each do |i| n = fib(i) ifib =is_fibonacci?(i) nfib = is_fibonacci?(n) puts"#{i} : #{ifib} , #{n} : #{nfib}" end |
基本上,它是一个接受
示例值
如果
如果
该函数比较第一个参数
然后查??看
如果这两种情况都不匹配,我们只是再次调用该函数,传入
示例:
1 | is_fibonacci?(i, current + before, current) |
将评估为
1 | is_fibonacci?(15, 5 + 3, 5 |
注意
Ruby 有一个很好的语法,其中
1 2 | if a < b puts"#{a} is greater than #{b}" |
与
完全相同
1 | puts"#{a} is greater than #{b}" if a < b |
它只是减少了行数,读起来更像英语。
首先它检查
1 | return true if current == i || i == 0 |
其次,它检查
1 | return false if current > i |
至少我们调用来计算下一个斐波那契数,将下一个数字作为当前和先前数字的总和传递给第二个参数,并将当前数字作为下一步的第三个参数。
1 | is_fibonacci?(i, current + before, current) |
请注意,最好的方法是将尾递归(如您的示例中所示)扩展为循环。