6

私は J の初心者で、演習としてフィボナッチ関数を作成しようとしています (言語を学習するときに常に 2 番目に作成する関数です)。自分のやり方で何が間違っているのか正確にはわかりません。私は暗黙のうちにそれを定義しようとしましたが、引数が 1 より大きい場合はハングします。

fib =: [ ` (($: (]-1)) + ($: (]-2))) @. (>&1)

また、明示的に作成しようとしましたが、うまくいきました。

fib =: 3 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'

3 を 13 に置き換えて、暗黙のうちに作成しようとしましたが、エラーがスローされました。

   fib =: 13 : 'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'
|spelling error
|   if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.
|   ^
|   fib=:    13 :'if. y>1 do. (fib (y-1)) + (fib (y-2)) else. y end.'

だから、私がここで間違っていることを正確に説明してくれる人を求めています。

4

2 に答える 2

4

わかりました、見つけました。暗黙のジェネレーターを介して再帰ブロックのみを実行し、このブロックを取得しました。

   13 : '(f y-1) + (f y-2)'
([: f 1 -~ ]) + [: f 2 -~ ]

それを元の曲に挿入すると、これが得られました。

fib =: [ ` (([: $: 1 -~ ]) + [: $: 2 -~ ]) @. (>&1)

そして、それは魅力のように機能します。" 0また、リストを受け入れるように最後に挿入しました。

于 2014-06-11T18:51:55.403 に答える
4

これは、より明確で簡潔な代替案です。

fibn =: (-&2 +&$: -&1)^:(1&<) M."0

より標準的な (疑似コード) 定義と比較してください。

fib(n) = fib(n-1) + fib(n-2) if n > 2 else n

まず、動名詞を使用する[ `withを使用する代わりに、 を使用することをお勧めします。の場合、接続詞を使用する方がより慣用的です。は「何もしない」を意味し、「一度行う」を意味するので、意図は明らかです。自明でない行動により適しています。@. (>&1)^:(1&<)f(n) if cond(n) else n^:^:0^:1@.

&第 2 に、 bond/compose 結合を使用すると、トレインが大幅に簡素化されます。とを繰り返し使用する[:]、かなり混乱し、不透明になります。を使用したリファクタリング&は、関連する操作をまとめます。最初に、 と の 2 つに分割しn、次に、これら 2 つの数値の を加算します。n-2n-1fibn

最後に"0、リストの処理とM.メモ化についてです。M.標準的な定義を直接実装するとfib(2)過度に呼び出されるため、パフォーマンスの観点からはかなり重要です。組み込みのメモ化副詞を使用して、ケーキを食べたり (簡単な定義)、それを食べたり (良いパフォーマンス) することができます。

この特定の定義の出典:このf0bページ.

于 2014-08-13T13:20:01.277 に答える