我正在尝试在OCaml中构建初始Trie结构,其中边缘为char。因此,字符串“ ESK”将被映射为:
label_features = []
dic = {}
dic['chipotle']='mexican'
dic['burger']='american'
label_features.append((dic,'food'))
NaiveBayesClassifier.train(label_features)
>><nltk.classify.naivebayes.NaiveBayesClassifier object at 0x000001704916BDD8>
我对此的定义是:
[('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
答案 0 :(得分:1)
请注意,编写该函数的更惯用的方式是
sealed trait Expr[T]
case class IntExpr(i: Int) extends Expr[Int]
case class BoolExpr(b: Boolean) extends Expr[Boolean]
def eval[T](e: Expr[T]): T = e match {
case IntExpr(i) => i
case BoolExpr(b) => b
}
然后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
第二个问题是该函数的名称不正确,因为它不会将字符串添加到现有的trie,而是从字符串构建了trie: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
或from_string
可能是更好的名称。 / p>
答案 1 :(得分:0)
已解决。 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 [])])])]