簡體   English   中英

備忘錄列表Ocaml

[英]Memoization list Ocaml

我有一個遞歸函數,我想用Mémoïsant重寫

我的遞歸函數:

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 list類型的表達式!

您不應該記住函數,而要記住函數的結果,例如,使用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),與計算三的冪的時間基本相同),第二,如果存在哈希沖突,則密鑰中的每個列表bucket將與參數列表進行比較。 結果,已記憶的功能與未記憶的功能具有相同的復雜性,性能更差,並且會消耗大量的內存。 值得嗎?

sum_cube,無需記憶。

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

具有記憶和跟蹤功能的sum_cube。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM