简体   繁体   中英

Memoization list Ocaml

I have a recursive function and I want the rewriting in the Mémoïsant

My recursive function:

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

and I tried with this:

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 ;;

I have an error:

This expression has type int list -> int but an expression was expected of type int list !!

You should memoize not the function, but the result of the function, eg, using your definition of 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

This will work, however there is a caveat. You're using a list of integers as a key. That means, that first the key is transformed to its hash (basically O(n), and will take basically the same amount of time as computing the power of three), second, if there is a hash collision, then every list in the bucket will be compared with the argument list. As a result, your memoized function has the same complexity as your non-memoized function, it has worse performance, and also consumes unbound amount of memory. Is it worthwhile?

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

Test :

#  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM