繁体   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