簡體   English   中英

新手F#trie實施出錯了

[英]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#中實現此數據結構的任何其他建議,我知道我必須做很多錯誤,因為我對這種語言很新。 我知道例如單詞插入函數是有缺陷的,因為它不檢查列表是否為空,因此它過早結束。 當我到達那里時,我想過那座橋。

先感謝您

先感謝您

  1. 你可能沒有觸發你的斷點,因為你沒有完全應用insertWords :它需要兩個curried參數,但你只傳遞單個參數wordChars 。也許你的意思是定義你的Trie類型呢?

     type Trie(inner : TrieNode) = member this.InsertWord(wordChars:char list) = TrieFunctions.insertWord wordChars inner 
  2. 好吧,你可以在[]包含所有的返回值,使它們成為單例列表,然后不包含對insertWords的遞歸調用。 但是,您的算法似乎有可能出現問題(無論哪種方式),因為您只獲得單例列表...

    請注意,您現在完全丟棄現有的subnodes列表 - 如果要附加到它的前面,請使用(insertWord wordChards.Tail node)::subnodes 但是,有時您需要替換現有條目而不是添加新條目,這將需要更多努力。

  3. 有幾個問題。 以下是一些可以幫助您入門的內容:

    • 盡量避免使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM