Last active
November 23, 2015 21:04
-
-
Save Nnwww/682f5a8331326431086b to your computer and use it in GitHub Desktop.
Trie in OCaml (I can't come up with smart implementation)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type trie = Trie of int option * char_to_children | |
and char_to_children = (char * trie) list | |
let empty = | |
Trie (None, []) | |
let example = | |
Trie (None, | |
[('i', Trie (Some 11, | |
[('n', Trie (Some 5, [('n', Trie (Some 9, []))]))])); | |
('t', | |
Trie (None, | |
[('e', | |
Trie (None, | |
[('n', Trie (Some 12, [])); ('d', Trie (Some 4, [])); | |
('a', Trie (Some 3, []))])); | |
('o', Trie (Some 7, []))])); | |
('A', Trie (Some 15, []))]) | |
let rec find ~fn = function | |
| [] -> None | |
| hd :: tl -> if fn hd then Some hd else find tl ~fn | |
let children_from_char children c = | |
let res = find children ~fn: | |
(function | |
| (x, _) -> if x = c then true else false) | |
in | |
match res with | |
| None -> None | |
| Some (fst, snd) -> Some snd | |
let update_children_list children c cons_trie = | |
let update (update, acc) ((fst, Trie(x, xs)) as e) = | |
if fst = c then | |
(true, ( fst, cons_trie (Some(x, xs)) ) :: acc) | |
else | |
(update || false, e :: acc) | |
in | |
let (success, result) = List.fold_left update (false, []) children in | |
if success then result | |
else (c, cons_trie None) :: result | |
let update_children children c trie = | |
update_children_list children c (fun _ -> trie) | |
let char_of_string word = | |
let len = String.length word in | |
let rec loop acc idx = | |
if idx < 0 then acc else loop (String.get word idx :: acc) (idx - 1) | |
in | |
loop [] (len - 1) | |
let lookup trie word = | |
let rec loop wl (Trie (x, xs)) = match (wl, xs) with | |
| (c :: ctl, _ :: _) -> | |
begin match children_from_char xs c with | |
| None -> None | |
| Some s -> loop ctl s | |
end | |
| (c :: ctl, []) -> None | |
| ([], _) -> x | |
in | |
loop (char_of_string word) trie | |
let insert (Trie(x, children)) word value = | |
let rec update_trie x xs = function | |
| [] -> Trie(Some value, xs) | |
| (c :: tl) as wl -> Trie (x, update_list xs wl) | |
and update_list xs = function | |
| [] -> invalid_arg "The length of a word is not enough." | |
| c :: tl -> | |
update_children_list xs c | |
(function | |
| None -> update_trie None [] tl | |
| Some (x, xs) -> update_trie x xs tl) | |
in | |
update_trie x children (char_of_string word) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment