0

私はルビーに慣れていないので、おそらくここで非常に初心者の間違いを犯していますが、答えを得るためにグーグルを試してみましたが、このコードが奇妙な動作をしている理由を理解できませんでした. このコードは非常に単純で、基本的な動的プログラミングを使用して中間結果をハッシュに格納し、後で計算を高速化するために使用します。

$existingSequence = {0 => 1, 1 => 2}


def fib(n)
  if $existingSequence.has_key? n
    return $existingSequence.values_at n;
  end

  if n == 0
    return 1;
  elsif n == 1
    return 2;
  end

  $existingSequence[n] = fib(n - 1) + fib(n - 2)
  return $existingSequence[n];
end

n = fib(2)
puts n

このコードは fib(1) と fib(0) を呼び出し、それぞれ 2 と 1 を返し、追加して 3 になるため、このコードは 3 を出力すると予想しています。しかし、出力は 1 と 2 です。

4

3 に答える 3

2

少し話題から外れますが、本質的に同じことを行う楽しい方法がありますが、Hashデフォルト値メカニズムを使用してHash、キャッシュだけでなく値の計算にも使用します。

fibs = { 0 => 0, 1 => 1 }.tap do |fibs|
  fibs.default_proc = ->(fibs, n) { fibs[n] = fibs[n-1] + fibs[n-2] }
end

fibs[9]
# => 34

注: これは自分で思いついたのではなく、ここから盗みました.

于 2011-02-06T16:03:08.787 に答える
2

Hash.values_at配列を返すため、コードがそうする場合、配列をfib(1) + fib(0)連結して一緒にして、答えを返します。それ以外の:[2][1][2, 1]

return $existingSequence.values_at n;

...代わりにこれを行う必要があります:

return $existingSequence[n]

ところで、フィボナッチ数列は伝統的に、1 と 2 ではなく、0 と 1 で始まります。

于 2011-02-06T06:10:14.863 に答える
1

の 2 行目は次のようにfibなります。

return $existingSequence[n]

それ以外の

return $existingSequence.values_at n

puts $existingSequenceをファイルの末尾に追加して、違いを確認します。

于 2011-02-06T06:11:34.887 に答える