请解释用于斐波纳契的Ruby哈希

时间:2017-08-01 18:24:14

标签: ruby

尝试理解以下代码,该代码返回方法调用中序列号的F(n)。它实际上来自一个较旧的SO帖子。我完全理解斐波那契数字。

fib = Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2]}
fib[6]  # => 8

我知道这是一个哈希,并且理解所有语法。我的绊脚石是行尾的操作 - h[k-1] + h[k-2]

也许我不完全理解递归方法。谢谢您的帮助!

1 个答案:

答案 0 :(得分:2)

该代码与以下内容相同:

fib = Hash.new do |h,k|
  if k < 2
    h[k] = k
  else 
    h[k] = h[k-1] + h[k-2]
  end
end

当您访问不属于散列fib的密钥时,它将默认为块中的任何内容,其中h是散列本身,而k是您的关键想要访问。

使用fib[6]评估if k < 2会返回false,因此会执行else子句:

h[k] = h[k-1] + h[k-2]
h[6] = h[6-1] + h[6-2]
h[6] = h[5] + h[4]

正如您所看到的,h[5]h[4]也尝试访问不存在的密钥,因此对两者都进行相同的评估,并且两者都从条件返回false if,所以:

h[5] = h[5-1] + h[5-2]
h[5] = h[4] + h[3]

h[4] = h[4-1] + h[4-2]
h[4] = h[3] + h[2]

同样,h[3]h[2]都会查找不存在的密钥,因此重复此过程:

h[3] = h[3-1] + h[3-2]
h[3] = h[2] + h[1]

h[2] = h[2-1] + h[2-2]
h[2] = h[1] + h[0]

最后,同样适用于h[1]h[0],但这次if中的条件将评估为true,因此现在它将返回h[k] = k }:

h[0] = 0
h[1] = 1

现在,在一路走下去之后,我们又回来了:

h[2] = h[1] + h[0]
h[2] = 1 + 0
h[2] = 1

h[3] = h[2] + h[1]
h[3] = 1 + 1
h[3] = 2

h[4] = h[3] + h[2]
h[4] = 2 + 1
h[4] = 3

h[5] = h[4] + h[3]
h[5] = 3 + 2
h[5] = 5

h[6] = h[5] + h[4]
h[6] = 5 + 3
h[6] = 8

所以:

fib[6]
#=> 8