【问题标题】:Creating char Trie in OCaml在 OCaml 中创建 char Trie
【发布时间】:2018-09-24 00:09:48
【问题描述】:

我正在尝试在 OCaml 中构建一个初始的 Trie 结构,其中边缘是字符。所以字符串“ESK”将被映射为:

[('E', [('S', [('K', [])])])]

我对此的定义是:

type trie = Trie of (char * trie) list

但是,在实现 add 函数时:

 let rec add_string str =
    let key = String.get str 0 in
    if String.length str = 1 then
      (key, empty_trie) :: []
    else
      (key, add_string (tail str)) :: []

对于add (tail str),编译器给了我:

Error: This expression has type (char * trie) list
       but an expression was expected of type trie

我对此有点困惑,因为我没有将trie 定义为(char * trie) list

tail 就是let tail str = String.slice str 1 (String.length str)empty_trie 就是let empty_trie = Trie([])

【问题讨论】:

    标签: functional-programming ocaml variant


    【解决方案1】:

    请注意,编写函数的更惯用方式是

    let rec add_string str =
      let key = str.[0] in
      if String.length str = 1 then
        Trie [key, empty_trie]
      else
        Trie [key, add_string (tail str)]
    

    那么add_string 有两个问题:首先它在每次迭代时重新分配一个新字符串。跟踪当前位置更简单高效:

    let add_string str =
      let rec add_string_aux pos str =
        if pos = String.length str then empty_trie
        else
          let key = str.[pos] in
          Trie [key, add_string_aux (pos+1) str] in
      add_string_aux 0 str
    

    第二个问题是该函数命名不当,因为它不会将字符串添加到现有的 trie,而是从字符串构建 trie:from_stringof_string 可能是更好的名称。

    【讨论】:

      【解决方案2】:

      已解决。 Trie 应该明确使用:

      let rec add_string str =
        let key = String.get str 0 in
        if String.length str = 1 then
          (key, empty_trie) :: []
        else
          (key, Trie (add_string (tail str))) :: []
      

      这将导致add_string "ESK" 产生:

      (char * trie) list = [('E', Trie [('S', Trie [('K', Trie [])])])]

      【讨论】:

      • 或者,如果您希望add_string 返回trie:分别为Trie [(key, empty_trie)]Trie [(key, add_string (tail str))]
      • 这是一个更好的主意。随意张贴作为答案,我会标记为已回答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-16
      • 2011-09-18
      • 1970-01-01
      相关资源
      最近更新 更多