【问题标题】:Insert implementation for a trie in Ocaml在 Ocaml 中插入 trie 的实现
【发布时间】:2017-03-19 01:23:21
【问题描述】:

我不知道如何更改 add 函数的代码。

type trie = Node of bool * (char * trie) list 

let explode word = 
       let rec explode' i acc = 
           if i < 0 then acc else explode' (i-1) (word.[i] :: acc) 
            in explode' (String.length word - 1) []

let rec exists w tr = match w, tr with
    | [], Node (b, _) -> b
    | h::t, Node (_, l) -> try exists t (List.assoc h l) with Not_found -> false

let rec add w tr = match w, tr with 
    | [], Node (_, l) -> Node (true, l)
    | h :: t, Node (b, l) -> try add t (List.assoc h l)   
                             with Not_found -> Node (false, (h, add t tr) :: l)

问题是当List.assoc h l 找到某些东西时,我没有跟踪我的结构,在递归调用期间没有构建Node,所以我丢失了数据。

例子:

# let empty = Node(true, []);;
 - : trie = Node (true, [])
# let w = explode "hi";;
val w : char list = ['h'; 'i']
# let ww = explode "hit";;
val ww : char list = ['h'; 'i'; 't']
# let tr = add w x;;
val tr : trie = Node (false, [('h', Node (false, [('i', Node (true, []))]))])
# add ww tr;;
- : trie = Node (false, [('t', Node (true, []))])

【问题讨论】:

    标签: ocaml trie


    【解决方案1】:

    看来您的基本计划是使用List.assoc 向下处理数据结构,然后在找到正确位置时添加新节点。如果您可以修改结构,这是有道理的。但是,您的数据结构是不可变的。对于不可变数据,您的基本计划必须是构建一个 数据结构,而不是修改旧数据结构。因此,您必须想象自己找到了正确的位置,同时沿途跟踪旧结构,然后从该位置开始构建新结构。

    这里有一些代码,它保存了一个关联列表,用于计算到目前为止看到的字符实例的数量。请注意,它返回一个新的关联列表,而不是修改旧的关联列表(这是不可能的):

     let rec add_char_count list char =
         match list with
         | [] -> [(char, 1)]
         | (hchar, hcount) :: t -> 
             if hchar = char then (hchar, hcount + 1) :: t
             else (hchar, hcount) :: add_char_count t char
    

    递归调用(hchar, hcount) :: add_char_count t char 是记住旧结构的地方。它从添加新字符之前的列表部分重建旧结构。

    【讨论】:

    • 我虽然有些情况你没有处理。但我可能是错的。
    • 谢谢,我会测试并做出相应的修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多