[英]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.