我正在使用aho-corasick算法来尝试使用F#更好一点,我遇到了Trie实现的问题,它们都是可变的或者不能进行尾调用优化。
我可以看到的基本问题是不可变数据结构必须“自下而上”构建,因为你无法改变他们所指向的内容,所以你的选择要么让它们变得可变,要么找出节点为你去(即在施工中递归)。
有没有办法在构造上使用尾调用优化来创建一个不可变的trie数据结构?(而不是通过复制来降低效率。)
答案 0 :(得分:8)
使用延续可以消除尾调用优化。以下是密钥和值分别为string
和int
type Trie =
| Data of string * int * Trie * Trie
| Leaf
let Insert start key value =
let rec inner current withNode =
match current with
| Data (currentKey, currentValue, left, right) ->
if key < currentKey then
inner left (fun left -> Data (currentKey, currentValue, left, right))
else
inner right (fun right -> Data (currentKey, currentValue, left, right))
| Leaf -> withNode (Data (key, value, Leaf, Leaf))
inner start (fun x -> x)
如果你想坚持使用不可变结构,消除副本会有点困难
答案 1 :(得分:1)
我在研究my code review post时发现了这篇文章,我已经在不可变的特里实现了。
使用映射表示链接而不是二叉树。