如何实现字典(Trie vs HashTable和重要问题)?

Den*_* S. 15 java algorithm lookup dictionary data-structures

我遇到了几个问题和文章,说java中的字典实现最好用try.但就我所见,他们中的大多数都没有解决重要问题.那么,接下来是一个现实世界的任务:

让我们假设我需要使用java来实现一个字典(让我们说像Lingvo,但更简单).对于我的特定任务,需要存储单词定义并执行快速字典查找.

请解决下一个问题:

  • 那我应该使用什么数据结构(Trie或HashTable)?
  • 如果我需要字典不区分大小写,它应该如何组织(搜索,数据结构)?
  • 如果我希望它(搜索,字典)区分大小写怎么办?

PS:代码示例受到高度赞赏.:)

提前感谢您的回答.

更新:如果我们在谈论Java中的标准DS实现,那么HashTable对于这个特定任务来说是最好的吗?为什么不使用HashMap,TreeMap或LinkedHashMap?

Kon*_*lph 16

我想在你的问题中只谈一点:

线索通用的字典的数据结构.原因是trie是(子)字符串搜索的专用搜索树.通常,您会对一般搜索树更感兴趣,例如二叉搜索树B树.

所有这些实现都依赖于字典元素的排序,并且它们都具有对数平均情况和最差情况运行时的常见操作.

哈希表,相比之下,不要求中的元素的相对顺序.相反,它需要的元素是可哈希平等相媲美.公共哈希表特征的最坏情况特征比树更差,即元素数量的线性.

但是,有点小心,哈希表操作的平均情况可以保持不变(即独立于容器大小).更重要的是,可以证明较慢的操作非常罕见.

在实践中,这意味着除了非常专业的用例外,哈希表击败了基于树的词典.

这样做的缺点是哈希表对其元素施加了任意看似的顺序.如果您有兴趣按排序顺序从字典中获取项目,则哈希表不适合您.

(还有其他有趣的字典实现,例如跳过列表,可以与搜索树和Bloom过滤器等概率实现相媲美.)

只有在处理字符串值字典时才能使用基于trie的实现,在这种情况下,它实际上通常是一个不错的选择,特别是如果字典中的许多字符串共享公共前缀并且相当短.

  • @ den-javamaniac`HashTable`是一个线程安全的`HashMap`(很像`Vector` vs`ArrayList`),因此当您知道多个线程不与它交互时,`HashMap`会更好.奇怪的是,`Collections.synchronizedMap(new HashMap())`比`HashTable`更快,似乎提供了相同的安全性.`TreeMap`要求它的键是'Comparable`并使用红黑树.`LinkedHashMap`使用左/右/父引用(IIRC)而不是数组.这类似于`ArrayList`和`LinkedList`之间的区别.就个人而言,在java中,我很少使用`Linked ...`集合. (2认同)
  • @Gugussee :(已编辑!)抱歉,你是对的.我以为我已经明确表示我正在谈论*通用*词典,并且只尝试字符串搜索.但再看一遍,这根本不清楚.我会更新我的答案. (2认同)