Ruby Fibonacci示例

时间:2016-10-17 02:35:12

标签: ruby

class Fibonacci
  def calc(n)
    return n if n < 2
    return calc(n - 1) + calc(n - 2)
  end
end

puts Fibonacci.new.calc(40)
>> 102334155

我想弄清楚这个程序。据我所知,如果它不是0或1,它会递归调用calc方法两次,但我不明白它是如何工作来获得序列的正确数字。

我知道这是我缺乏经验的表现,但有人可以向我解释这是如何正确计算纤维序列的吗?它只是没有点击我。

2 个答案:

答案 0 :(得分:2)

让我们以n == 3为例:

首次迭代:n不是01,因此保护条款不会成立。所以我们计算calc(2) + calc(1)

致电calc(2):致电calc(1) + calc(0)。这两个都满足guard子句,因此分别返回10。所以这个计算的结果是1

致电calc(1):保护条款触发并返回1

我们现在将两个1加起来,得到正确的结果2

尝试对n的更高值应用相同的推理,并记住此实现非常浪费,因为它会重复计算相同的值。

答案 1 :(得分:2)

当您无法理解代码正在执行的操作时,您可能不得不使用puts语句对其进行腌制。对于递归,它还有助于改变缩进以显示方法何时调用自身以及何时返回方法。这是您为代码执行此操作的一种方法。

INDENT = 4
@tabs = 0

def calc(n)
  pr_indent
  puts "entered calc(#{n})"
  if n < 2
    pr_indent
    puts "returning n=#{n}"
    @tabs -= 1
    return n
  end
  pr_indent
  puts "calling calc(#{n-1})"
  @tabs += 1
  m1 = calc(n-1)
  pr_indent
  puts "calc(#{n-1}) returned m1=#{m1} to calc(#{n})"
  pr_indent
  puts "calling calc(#{n-2})"
  @tabs += 1
  m2 = calc(n-2)
  pr_indent
  puts "calc(#{n-2}) returned m2=#{m2} to calc(#{n-1})"
  pr_indent
  puts "returning m1+m2=#{m1+m2}"
  @tabs -= 1
  m1+m2
end

def pr_indent
  print "#{' '*(@tabs*INDENT)}"
end

现在执行

calc(4)

导致打印以下内容。我不会提供正在运行的注释,当您在阅读代码时阅读打印内容时,它应该是不言自明的。

entered calc(4)
calling calc(3)
    entered calc(3)
    calling calc(2)
        entered calc(2)
        calling calc(1)
            entered calc(1)
            returning n=1
        calc(1) returned m1=1 to calc(2)
        calling calc(0)
            entered calc(0)
            returning n=0
        calc(0) returned m2=0 to calc(1)
        returning m1+m2=1
    calc(2) returned m1=1 to calc(3)
    calling calc(1)
        entered calc(1)
        returning n=1
    calc(1) returned m2=1 to calc(2)
    returning m1+m2=2
calc(3) returned m1=2 to calc(4)
calling calc(2)
    entered calc(2)
    calling calc(1)
        entered calc(1)
        returning n=1
    calc(1) returned m1=1 to calc(2)
    calling calc(0)
        entered calc(0)
        returning n=0
    calc(0) returned m2=0 to calc(1)
    returning m1+m2=1
calc(2) returned m2=1 to calc(3)
returning m1+m2=3

calc(4)返回3