F# compute height of a trie node -
i trying implement trie structure in f# method compute height of every node.
this came far:
type trienode = | subnodes of char * bool * trienode list | nil member this.char = match | nil -> ' ' | subnodes(c,weh,subnodes) -> c member this.getchild(c:char) = match | nil -> [] | subnodes(c,weh,subnodes) -> if subnodes.length > 0 [ (list.filter(fun (this:trienode) -> this.char = c) subnodes).head ] else [] member this.awordendshere = match | nil -> false | subnodes(c,weh,subnodes) -> weh module triefunctions = let rec insertword (wordchars:char list) = function | nil -> subnodes(' ', false, (insertword wordchars nil)::[]) //daca aici inca nu e cel putin un nod atunci fa nodul radacina standard adica nodul care nu e sfarsit de cuvant si //are caracterul ' ' si incepe sa ii construiesti lui subnodurile | subnodes(c, weh, subnodes) node -> if(wordchars.length = 1) subnodes(wordchars.head,true,[]) else let child = node.getchild(wordchars.head) if child = [] subnodes(wordchars.head,false,(insertword wordchars.tail node)::subnodes ) else subnodes(wordchars.head,false,(insertword wordchars.tail child.head)::subnodes ) let stringtocharlist(s:string) = list.ofseq s type trie(inner : trienode) = member this.insertword(wordchars:char list) = trie(triefunctions.insertword wordchars inner) member this.insertword(str:string) = trie(triefunctions.insertword (triefunctions.stringtocharlist str) inner) let trie = trie(subnodes(' ',false,list.empty)) .insertword("abc") .insertword("abcd") .insertword("abcd") .insertword("abcde") .insertword("abcdef") .insertword("ab123cd") .insertword("abc123d") .insertword("abc132d")
now trying write height computing function. easy write if binary tree in tree each node has list of subnodes don't know how recurrently traverse thing in f#.
this came far using list fold operation doesn't compile:
module nodefunctions = let rec nextlevel(node:trienode,curlevel:int) = function | nil -> curlevel | subnodes(_,_,subnodes) -> list.fold (fun acc (node:trienode,_,_) -> let res = nextlevel(node,curlevel+1) , if( acc > res) acc else res) curlevel subnodes
any ideas how might rewrite function make work? or ideas how else achieve goal should not right idea?
thank in advance
thinking trie more initial approach close required start same letter. here's working trie uses chars original idea , not strings. leave reader exercise implement string nodes , leafs.
module trie = type node = node of (char * bool * node) list let empty = node([]) let partition c = function | node(nodes) -> list.partition (fun (ct, _, _) -> ct = c) nodes let rec insert wordchars node = match wordchars, node | c::cx, node([]) -> node([c, cx.isempty, (insert cx empty)]) | c::cx, _ -> match partition c node | (ct, weh, children)::_, others -> node((c, (weh || cx.isempty), insert cx children)::others) | [] , others -> node((c, cx.isempty, insert cx empty)::others) | [], _ -> node let insertword (s:string) node = insert (list.ofseq s) node
and test
let rec nextlevel (curlevel:int) = function | trie.node([]) -> curlevel | trie.node(nodes) -> list.fold (fun acc (_, _, node) -> let res = nextlevel (curlevel + 1) node if (acc > res) acc else res) curlevel nodes let rec print acc = function | trie.node(nodes) -> list.iter (fun (c, w, node) -> let str = acc + c.tostring() if w printfn "%s" str print str node) nodes let trie = trie.empty |> trie.insertword("abc") |> trie.insertword("abcd") |> trie.insertword("abcd") |> trie.insertword("abcde") |> trie.insertword("abcdef") |> trie.insertword("ab123cd") |> trie.insertword("abc123d") |> trie.insertword("abc132d") printf "%d\n" (nextlevel 0 trie) print "" trie
output
7 abc abc132d abc123d abcd abcde abcdef ab123cd
Comments
Post a Comment