[ocaml] LZW-simple
Viewer
*** This page was generated with the meta tag "noindex, nofollow". This happened because you selected this option before saving or the system detected it as spam. This means that this page will never get into the search engines and the search bot will not crawl it. There is nothing to worry about, you can still share it with anyone.
- let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- (**
- LZW encode : string -> int list
- *)
- let encode s =
- let dict = Hashtbl.create (String.length alphabet) in
- let add_to_dictionary w = Hashtbl.add dict w (Hashtbl.length dict + 1) in
- let is_in_dictionary = Hashtbl.mem dict in
- let input = ref "" in
- let output = ref [] in
- let emit_index_of w = output := Hashtbl.find dict w :: !output in
- alphabet |> String.iter (fun c -> c |> String.make 1 |> add_to_dictionary) ;
- for i = 0 to String.length s - 1 do
- let c = String.sub s i 1 in
- let w = !input in
- let wc = w ^ c in
- if wc |> is_in_dictionary then
- input := wc
- else begin
- emit_index_of w ;
- input := c ;
- add_to_dictionary wc
- end
- done ;
- emit_index_of !input ;
- List.rev !output
- (**
- LZW decode : int list -> string
- *)
- let decode codes =
- match codes with
- | [] -> ""
- | first_code :: rest_codes ->
- let dict = Hashtbl.create (String.length alphabet) in
- let add_to_dictionary w = Hashtbl.add dict (Hashtbl.length dict + 1) w in
- let word_for = Hashtbl.find_opt dict in
- let first_symbol_of s = String.sub s 0 1 in
- alphabet |> String.iter (fun c -> c |> String.make 1 |> add_to_dictionary) ;
- let first = (match word_for first_code with Some w -> w | None -> failwith "invalid input") in
- let output = ref first in
- let previous = ref first in
- let emit w = output := !output ^ w ; previous := w in
- rest_codes |> List.iter (fun code ->
- match word_for code with
- | Some w ->
- let v = !previous ^ first_symbol_of w in
- add_to_dictionary v ;
- emit w
- | None ->
- let v = !previous ^ first_symbol_of !previous in
- add_to_dictionary v ;
- emit v
- );
- !output
- (* ---------------------------------------------------------------- *)
- let test_phrase = "TOBEORNOTTOBEORTOBEORNOT"
- let _ =
- print_endline test_phrase ;
- let encoded = encode test_phrase in
- List.iter (Printf.printf "%d ") encoded ; print_endline "" ;
- let decoded = decode encoded in
- print_endline decoded
Editor
You can edit this paste and save as new: