3

フィボナッチ数を見つけるために、互いによく似た 2 つの例を見つけました。

  • ラムダ

    fibonacci = ->(x){ x < 2 ? x : fibonacci[x-1] + fibonacci[x-2] }
    fibonacci[6]  # => 8
    
  • ハッシュ

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

以前はRubyでハッシュとラムダの両方を使用していましたが、これは好きではありません。これは、関数を格納するより多くの方法です。

if x < 2
  x
else
 fibonacci[x-1] + fibonacci[x-2]
  1. これがどのように機能しているのか詳しく説明できますか?これは再帰を使用していますか?
  2. このようなハッシュとラムダの違いは何ですか?
4

3 に答える 3

4

最初のケースでは、再帰的に呼び出される再帰を定義しています。

ハッシュの場合、値も再帰的に計算されますが、格納されてから、結果を与えるためにアクセスされます。

  • ラムダ

    fibonacci = ->(x){ x < 2 ? x : fibonacci[x-1] + fibonacci[x-2] }
    fibonacci[6]
    fibonacci # => <Proc:0x2d026a0@(irb):5 (lambda)>
    
  • ハッシュ

    fibonacci = Hash.new{ |h,x| h[x] = x < 2 ? x : h[x-1] + h[x-2] }
    fibonacci[6] 
    fibonacci # => {1=>1, 0=>0, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8}
    

場合によっては、メモリにフットプリントを残さないのに対し、ハッシュは計算された値を保持し続けます。したがって、必要なものによって異なります。

fibonacci[6]もう一度アクセスする必要がある場合、ラムダは結果を再計算しますが、ハッシュは計算をやり直すことなくすぐに結果を返します。

于 2013-09-11T07:22:27.397 に答える
-1

このようなハッシュとラムダの違いは何ですか?

ラムダとハッシュには共通点はありません。あなたの質問は、次のように尋ねています。

メソッドと配列の違いは何ですか?

ハッシュが存在しないキーのデフォルト値を指定できるというだけです:

h = Hash.new(10)

h["a"] = 2
puts h["a"]
puts h["b"]

--output:--
2
10 

ハッシュは、デフォルト値を動的に指定する方法も提供します: ブロックを提供できます。次に例を示します。

h = Hash.new do |h, key|
  h[key] = key.length
end

puts h['hello']
puts h['hi']
p h

--output:--
5
2
{"hello"=>5, "hi"=>2}

存在しないキーにアクセスすると、ブロックが呼び出され、ブロックは必要なことを実行できます。そのため、誰かが巧妙に、ハッシュを作成し、フィボナッチ数を計算するデフォルト値を指定できることを発見しました。仕組みは次のとおりです。

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

これにより、キーや値のないハッシュであるハッシュ h が作成されます。次に書く場合:

puts h[3]

...3 は存在しないキーなので、ブロックは引数 h と 3 で呼び出されます。ブロック内の else 句が実行され、次のようになります。

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

また:

h[2] +  h[1]

しかし、そのステートメントを評価するには、ruby は最初に h[2] を評価する必要があります。しかし、Ruby がハッシュで h[2] を検索すると、キー 2 は存在しないキーであるため、ブロックは引数 h と 2 で呼び出され、次のようになります。

(h[2-1] + h[2-2]) + h[1]

また:

(h[1] + h[0])    + h[1]

そのステートメントを評価するには、最初の h[1] を評価する必要があります。Ruby がハッシュで h[1] を検索しようとすると、1 は存在しないキーであるため、h と​​ 1 の引数でブロックが呼び出されます。今度は if 分岐が実行され、次のことが起こります。

 h[1] = 1

h[1] の値として 1 が返され、次のようになります。

 (1 + h[0])      + h[1]

次に ruby​​ は h[0] を検索し、0 は存在しないキーであるため、ブロックは引数 h と 0 で呼び出され、if 節が実行されてこれが行われます。

h[0] = 0

h[0] の値として 0 が返され、次のようになります。

(1 + 0)        + h[1]

次に、ruby はハッシュで h[1] を検索します。今回はキー 1 が存在し、値が 1 であるため、次のようになります。

(1 + 0)        + 1

そしてそれは 2 に等しいので、h[3] は 2 に等しく設定されます。h[3] を呼び出すと、次の出力が得られます。

puts h[3]
p h

--output:--
2
{1=>1, 0=>0, 2=>1, 3=>2}

ご覧のとおり、以前の計算はすべてハッシュにキャッシュされています。つまり、他のフィボナッチ数に対してこれらの計算を再度実行する必要はありません。

于 2013-09-11T09:14:46.300 に答える