Я пытаюсь реализовать структуру Frie в F # с методом для вычисления высоты каждого узла.
Это то, что я до сих пор придумал:
type TrieNode =
| SubNodes of char * bool * TrieNode list
| Nil
member this.Char = match this with | Nil -> ' '
| SubNodes(c,weh,subnodes) -> c
member this.GetChild(c:char) = match this with | Nil -> []
| SubNodes(c,weh,subnodes) -> if subnodes.Length > 0 then [ (List.filter(fun (this:TrieNode) -> this.Char = c) subnodes).Head ] else []
member this.AWordEndsHere = match this with | 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) as node ->
if(wordChars.Length = 1) then
SubNodes(wordChars.Head,true,[])
else
let child = node.GetChild(wordChars.Head)
if child = [] then
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")
Теперь я пытаюсь написать свою функцию вычисления высоты. Это было бы очень легко написать, если бы это было двоичное дерево, но в этом дереве у каждого узла есть список подузлов, поэтому я не знаю, как периодически проходить через F #
Это то, что я до сих пор придумал, используя операцию свертывания списка, но она не компилируется:
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) and
if( acc > res) then acc else res) curlevel subnodes
Есть идеи, как мне переписать эту функцию, чтобы она работала?
Или какие-либо идеи о том, как еще достичь моей цели, если это не будет правильной идеей?
Заранее спасибо