(* In this script, we will implement a simple hash table. * In our implementation, the keys are strings and the table has * polymorphic values. * * Part of the implementation can be found in the book Introduction to Objective Caml by Jason Hickey. P92 *) (* create an array of random numbers *) let random_numbers = Array.init 37 (fun x -> Random.int 100 + 1) ;; let random_length = Array.length random_numbers ;; type hash_info = { mutable hash_index : int; mutable hash_value : int; };; let hash_char info c = let i = Char.code c in let index = (info.hash_index + i + 1) mod random_length in info.hash_value <- (info.hash_value * 3 ) lxor random_numbers.(index); info.hash_index <- index ;; let hash s = (* compute the hash of a string *) let info = { hash_index = 0; hash_value = 0 } in for i = 0 to String.length s - 1 do hash_char info s.[i] done; info.hash_value ;; type 'a hash_entry = { key : string; value : 'a };; type 'a hash_table = 'a hash_entry list array ;; let create () = Array.make 101 [] ;; (* add functino adds {key ;value} to the hash table. however * it does not check if the key has already existed. One of the * consequences is we may have multiple values corresponding to * the same key *) let add table key value = let index = (hash key) mod (Array.length table) in table.(index) <- {key = key; value = value} :: table.(index) ;; (* find function will find the corresponding value of the given key. * In case of multiple values, it returns the first one when it * walks through the chain. If the key does not exist, it raises * Not_found *) let find table key = let index = (hash key) mod (Array.length table) in find_entry key table.(index) ;; let rec find_entry (key :string) = function {key = key' ; value = value } ::_ when key' = key -> value | _ :: entries -> find_entry key entries | [] -> raise Not_found ;; (* delete function will remove the key from the hash table. In the case that * there are multiple values corresponding to the same key, the function removes * the first value when it walks through the chain. *) let delete table key = let index = (hash key) mod (Array.length table) in let entries = table.(index) in let rec del part = function | [] -> ([], false) | ({key = key'; value = value} as hd) :: tl -> if key = key' then (List.rev part @ tl, true) else del (hd::part) tl in let (res_lst, flag) = del [] entries in match flag with | false -> print_string "key does not exist. No change occurs" | true -> table.(index) <- res_lst ;; (* replace function will update the value of a given key. In the case that * there are multiple values corresponding to the same key, the function updates * the first value when it walks through the chain. If the key does not exist * the function will raise Not_found. *) let replace table key value = let index = (hash key) mod (Array.length table) in let entries = table.(index) in let rec rep part = function | [] -> ([], false) | {key = key'} as hd :: tl -> if key = key' then let new_entry = {key;value} in (List.rev (new_entry::part) @ tl, true) else rep (hd::part) tl in let (res_lst, flag) = rep [] entries in match flag with | false -> raise Not_found | true -> table.(index) <- res_lst ;;
Saturday, January 31, 2015
Simple Implementation of Hash Table in OCaml
Labels:
Ocaml
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment