斐波那契与红宝石

时间:2018-08-29 02:08:36

标签: ruby

This是个问题,我已解决:

@cache={}
@cache[1]=0
@cache[2]=1

def fib(n)
  @fibs[n-1]
end

def fib_m(n)
  @cache[n] ||= fib_m(n-1) + fib_m(n-2)
end

@fibs=[]
@fibs=(1..100000).map{|n| fib_m(n)}

但是这看起来很hacky。似乎我正在将缓存加倍,并且我必须对一些上限进行硬编码。有没有更清洁的方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

  

是否有一种更清洁的方法?

您可以分配default_proc来动态计算丢失的哈希值:

fib = { 0 => 0, 1 => 1 }
fib.default_proc = ->(f, n) { f[n] = f[n-1] + f[n-2] }

fib[10]
#=> 55

fib
#=> {0=>0, 1=>1, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8, 7=>13, 8=>21, 9=>34, 10=>55}

请注意,此方法受Ruby的堆栈大小限制。

答案 1 :(得分:0)

如果在Ruby中启用了尾部调用优化,则可能会递归地获得相同的结果,从而更快,更少的内存消耗和更优雅的体验。

RubyVM::InstructionSequence.compile_option = {
  tailcall_optimization: true,  
  trace_instruction: false  
}

def fib(curr = 1, acc = 0, n)
  n <= 0 ? acc : fib(acc, curr + acc, n - 1)
end

fib(100_000).to_s.length
#⇒ 20899