1

重複の可能性:
メモ化と末尾再帰を組み合わせる

したがって、以下は私が書いたコードであり、累積変数を使用して最適化された末尾呼び出しです。

let rec counter init count = 
    if init = 1 then count + 1 else
    match init with
    | Even value -> (counter (value/2)  (1 + count))
    | Odd value -> (counter ((3 * value) + 1) (count+1))

let SeqBuilder (initval:int) : int =
    counter initval 0

これをどのようにメモしますか?メモ化しようとしたときに遭遇した問題は、再帰呼び出しがメモ化オブジェクトに移動する必要があるため、再帰オブジェクトが必要なことです。

それとももっと簡単で、私は経験が浅いだけですか?

4

1 に答える 1

3

F# では、再帰的な値(言及した再帰オブジェクトなど) を定義できるためmemoize2、メモ化を行う関数がある場合 (2 つの引数の関数を使用して、counter.

let rec counter = memoize2 (fun init count ->
  if init = 1 then count + 1 else 
  match init with 
  | Even value -> (counter (value/2) (1 + count)) 
  | Odd value -> (counter ((3 * value) + 1) (count+1)) )

このような再帰参照は危険な場合があるため、F# はいくつかの実行時チェックを挿入します。これについて通知する警告も表示FS0040されますが、この場合、再帰は正しいです (再帰参照が初期化中にアクセスされた場合、問題が発生する可能性があります。ここでは、関数が既に宣言されている場合にのみ後で使用するため、すべてが大丈夫)。を追加することで、警告を無効にすることができます#nowarn "40"

于 2010-09-18T03:24:35.150 に答える