2011-02-15 73 views
4

我试图在F#中实现trie数据结构。 我有一些问题。 我无法调试单词插入功能。我的这个函数里没有任何断点出现了崩溃,但是我没有看到任何错误。 另外,如果我正确地实施了这件事,我会有很大的怀疑。 反正这里是代码:新手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) ->[ (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#中实现这个数据结构是欢迎的我知道我必须做很多错误的事情,因为我对这种语言很陌生。我知道例如单词插入函数有缺陷,因为它不检查列表是否为空,所以它过早地结束。当我遇到它时,我想穿过那座桥。

预先感谢您

预先感谢您

+0

没有确定就不想编辑 - 你的意思是一棵树,对吧? 列表和二叉树的扩展? – 2011-02-15 20:52:57

+0

最后的trie值最终是type(Trie - > Trie) - 这表明它正在部分地评估插入字 – Jimmy 2011-02-15 21:00:17

回答

4
  1. 你可能无法触发您的断点,因为你没有充分运用insertWords:它需要两个参数,咖喱,但你只传递单个参数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"
1

关于你的第一个问题,@kvb说,你申请部分insertWord。在定义它,你要指定一个明确的说法wordChars,通过使用function结构模式匹配你基本上添加TrieNode类型的第二个参数让你的函数结束了以下特征:

insertWord : char list -> TrieNode -> TrieNode 

由于您调用InsertWord(这只是insertWord的包装),您只提供一个参数(char列表),该函数将不会被调用,但您会得到一个函数,期望返回TrieNodeInsertWord的签名表明:

InsertWord : wordChars:char list -> (TrieNode -> TrieNode) 

注意括号。

你可能会想你的情况提供Nil因为概念上你伸出的空特里:

let trie = Trie(SubNodes(' ',false,List.empty)).InsertWord(['g';'i';'g';'i']) Nil 

你会发现一个线索结构在这里的示例实现:http://lepensemoi.free.fr/index.php/2009/10/15/trie-and-anagrams-with-f