尝试理解以下代码,该代码返回方法调用中序列号的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]
也许我不完全理解递归方法。谢谢您的帮助!
答案 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