2016-12-07 4 views
0

私は、再帰関数を持っていると私はMémoïsantメモ化リストOCamlの

マイ再帰関数で書き換えたい:

let rec sum_cube l = 
    match l with 
    | [] -> 0 
    | x :: s -> (x * x * x) + sum_cube s 

をし、私はこれを試してみました:

let memo = Hashtbl.create 17 
let rec sum_cub_memo l = 
    try 
     Hashtbl.find memo l 
    with Not_found -> 
     let fn = function 
     | [] -> 0 
     | x::s -> (x * x * x) sum_cub_memo s 
     in 
     Hashtbl.add memo l fn 

fn ;; 

私が持っていますエラー:

この式の型はです。int list - > intが表現されましたが、タイプはintリストです!

+0

表現? – melpomene

+0

ああ。 'fn'を詳しく見てください。それは何ですか?どうやって使ってるの? – melpomene

+0

@melpomene Hashtbl.addメモl fn – CamlX

答えて

0

あなたは機能が、関数の結果をないmemoizeべきで、例えば、sum_cubeのあなたの定義を使用して:

let sum_cube_memo xs = 
    try Hashtbl.find memo xs with Not_found -> 
    let res = sum_cube xs in 
    Hashtbl.add memo xs res; 
    res 

これは動作しますが、しかし注意点があります。整数のリストをキーとして使用しています。つまり、最初にキーはハッシュ(基本的にはO(n)に変換され、基本的には3の累乗を計算するのと同じ時間量がかかります)、次に、ハッシュの衝突がある場合は、バケットは引数リストと比較されます。その結果、あなたのメモされた機能は、あなたのメモされていない機能と同じ複雑さを持ち、パフォーマンスが悪くなり、またメモリの量も消費されます。それは価値がありますか?

+0

この式の型はintですが、式はint型の式が必要です。 – CamlX

+0

これは、(はい、私はオラクルだからです)、両方の定義があります。それはあなたのもの(間違ったもの)、もう一つは私のもの(正しいもの)です。彼らは両方とも同じグローバル変数 'memo'を使用しています。 1つの定義は 'int list - > int'型の関数を' memo'に格納しようとしていますが、もう1つは計算結果( 'int'型)を格納しようとしています。だから、クリーンアップ、あなたのコード、間違った定義を削除するか、トップレベルで作業している場合は 'memo'値を再作成してください。 – ivg

0

sum_cube without memorization.

let sum_cube l = 
    let cube x =x*x*x in 
    List.fold_left (fun acc x -> acc+cube x) 0 l 

sum_cube with memorization and trace.

let sum_cube l = 
    let memo = Hashtbl.create 17 in 
    let cube_memo x = 
    try 
     let xcube= Hashtbl.find memo x in 
     Printf.printf "find %d -> %d\n" x xcube; 
     xcube 
    with Not_found -> 
     let xcube=x*x*x in 
     Printf.printf "add %d -> %d\n" x xcube; 
     Hashtbl.add memo x xcube; 
     xcube 
    in 
    List.fold_left (fun acc x -> acc+cube_memo x) 0 l 

テスト:

# sum_cube [4;4;2;3;4;2];; 
add 4 -> 64 
find 4 -> 64 
add 2 -> 8 
add 3 -> 27 
find 4 -> 64 
find 2 -> 8 
- : int = 235 
関連する問題