问题是在不使用任何存储和迭代方法的情况下在函数式语言中实现前缀树(Trie)。
我正在努力解决这个问题。我该如何处理这个问题?你能给我一个精确的算法或链接,它显示已经用任何功能语言实现了一个吗?
我为什么要这么做=>创建一个具有
功能的简单搜索引擎为什么我要使用功能语言=>我想进一步提高解决问题的能力。
注意:由于这是我的爱好项目,我将首先实现基本功能。
编辑:
i。)我的意思是“不使用存储”=>我不想使用变量存储(ex int a),引用变量,数组。我想通过递归计算结果,然后将结果显示在屏幕上。
ii。)我写了一些内容然后我已经删除了,因为我写的内容让我很生气。很抱歉没有表现出我的努力。
答案 0 :(得分:4)
看看haskell的Data.IntMap
。它是纯粹的功能实现
Patricia trie并且它source非常易读
bytestring-trie包将此方法扩展为ByteStrings
随附的文件Fast Mergeable Integer Maps也是可读的。它逐步描述了实现:从二进制尝试到大端patricia树 这篇文章很少摘录。
最简单的是,二进制trie是一个完整的深度二叉树 等于键中的位数,每个叶子都是 为空,表示相应的键未绑定或已满 它包含相应密钥所在的数据 界。这种trie样式可以用标准ML表示为
datatype 'a Dict = Empty | Lf of 'a | Br of 'a Dict * 'a Dict
要在二进制trie中查找值,我们只需读取它的位 钥匙,按照指示向左或向右移动,直到我们到达一片叶子。
fun lookup (k, Empty) = NONE | lookup (k, Lf x) = SOME x | lookup (k, Br (t0,t1)) = if even k then lookup (k div 2, t0) else lookup (k div 2, t1)
答案 1 :(得分:3)
不可变数据结构实现的关键点是数据和结构的共享。要更新对象,您应该使用尽可能多的共享节点创建它的新版本。具体地,可以使用以下方法。
考虑这样一个特里(来自Wikipedia):
想象一下,你还没有添加“inn”这个词,但你已经有了“in”这个词。要添加“inn”,您必须添加“inn”来创建整个trie的新实例。但是,您不必强制复制整个事物 - 您只能创建根节点的新实例(没有标签)和正确的banch。新的根节点将指向新的右侧banch,但是指向旧的其他分支,因此每次更新时大部分结构都与之前的状态共享。
但是,您的密钥可能很长,因此每次重新创建整个分支仍然耗费时间和空间。为了减轻这种影响,您也可以在一个节点内共享结构。通常,每个节点是所有可能结果的向量或映射(例如,在具有标签“te”的图片节点中具有3个结果 - “a”,“d”和“n”)。有大量不可变映射的实现(Scala,Clojure,请参阅它们的存储库以获取更多示例)并且Clojure还具有优秀的implementation不可变向量(实际上是树)。
创建,更新和搜索结果尝试的所有操作可以递归地实现,而没有任何可变状态。