[英]newbie F# trie implementation gone wrong
我試圖在F#中實現trie數據結構。 我有一些問題。 我無法調試單詞插入功能。 我在這個函數中的任何斷點都沒有遇到崩潰但我沒有看到任何錯誤。 如果我把事情做得對,我也有嚴重的疑慮。 無論如何這里是代碼:
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) ->[ (List.filter(fun (this:TrieNode) -> this.Char = c) subnodes).Head ]
member this.AWordEndsHere = match this with | Nil -> false
| SubNodes(c,weh,subnodes) -> weh
module TrieFunctions =
let rec insertWord (wordChars:char list) = function
| Nil -> SubNodes(wordChars.Head, false, [])
| SubNodes(c, weh, subnodes) as node ->
let child = node.GetChild(wordChars.Head)
if child = [] then
SubNodes(wordChars.Head,false,[insertWord wordChars.Tail node])
else
SubNodes(wordChars.Head,false,[insertWord wordChars.Tail child.Head])
type Trie(inner : TrieNode) =
member this.InsertWord(wordChars:char list) = TrieFunctions.insertWord(wordChars)
let trie = Trie(SubNodes(' ',false,List.empty)).InsertWord(['g';'i';'g';'i'])
所以我的問題是:
1.如何獲得insertWord函數的調試權限? 我為什么不現在得到它? 為什么我沒有看到錯誤?
2.如何使函數插入單詞返回一個TrieNode對象列表,這樣我就不必圍繞方括號(“[”,“]”)包圍調用。 我認為這是一個錯誤。
3.您可以向我提供有關在F#中實現此數據結構的任何其他建議,我知道我必須做很多錯誤,因為我對這種語言很新。 我知道例如單詞插入函數是有缺陷的,因為它不檢查列表是否為空,因此它過早結束。 當我到達那里時,我想過那座橋。
先感謝您
先感謝您
你可能沒有觸發你的斷點,因為你沒有完全應用insertWords
:它需要兩個curried參數,但你只傳遞單個參數wordChars
。也許你的意思是定義你的Trie
類型呢?
type Trie(inner : TrieNode) = member this.InsertWord(wordChars:char list) = TrieFunctions.insertWord wordChars inner
好吧,你可以在[]
包含所有的返回值,使它們成為單例列表,然后不包含對insertWords
的遞歸調用。 但是,您的算法似乎有可能出現問題(無論哪種方式),因為您只獲得單例列表...
請注意,您現在完全丟棄現有的subnodes
列表 - 如果要附加到它的前面,請使用(insertWord wordChards.Tail node)::subnodes
。 但是,有時您需要替換現有條目而不是添加新條目,這將需要更多努力。
有幾個問題。 以下是一些可以幫助您入門的內容:
Head
,特別是因為當你調用它時,你並不總是知道你的列表是非空的。 Trie
插入一個單詞時,除了第一個字符之外你都會掉線! 同樣,您也需要重新考慮遞歸調用。 TrieNode
類型有一點問題。 你能寫出你想要看到的結果,它只包含兩個單詞"in"
和"to"
嗎? 關於你的第一個問題,正如@kvb所說,你部分應用了insertWord
。 在定義它時,您指定了一個顯式參數wordChars
並且通過使用function
構造進行模式匹配,您基本上添加了TrieNode
類型的第二個參數,因此您的函數最終會得到以下簽名:
insertWord : char list -> TrieNode -> TrieNode
由於在調用InsertWord
(這只是一個包裝insertWord
),你只提供一個參數(一個字符列表)功能將不會被調用,但你會得到一個函數期待一個TrieNode
回來。 InsertWord
的簽名清楚地表明了這一點:
InsertWord : wordChars:char list -> (TrieNode -> TrieNode)
注意括號。
你可能想要在你的情況下提供一個Nil
,因為從概念上你擴展了一個空的trie:
let trie = Trie(SubNodes(' ',false,List.empty)).InsertWord(['g';'i';'g';'i']) Nil
你會在這里找到一個trie結構的示例實現: http : //lepensemoi.free.fr/index.php/2009/10/15/trie-and-anagrams-with-f
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.