【发布时间】:2009-09-05 09:35:12
【问题描述】:
我想写一本字典。我应该使用什么算法/结构?
每个单词或短语都有相应的说明(示例、视频、图片等)。应该可以轻松添加/删除单词和修改描述。快速访问比快速添加/删除更重要。应该可以根据描述中的一些信息过滤单词。有些描述可能是半空的。
我正在考虑一些索引,其中包含单词和这些单词在字典文件中的位置。如何从描述中快速搜索到一些信息?
【问题讨论】:
标签: dictionary indexing
我想写一本字典。我应该使用什么算法/结构?
每个单词或短语都有相应的说明(示例、视频、图片等)。应该可以轻松添加/删除单词和修改描述。快速访问比快速添加/删除更重要。应该可以根据描述中的一些信息过滤单词。有些描述可能是半空的。
我正在考虑一些索引,其中包含单词和这些单词在字典文件中的位置。如何从描述中快速搜索到一些信息?
【问题讨论】:
标签: dictionary indexing
字典一般建立在树之上,最常见的是自平衡树。最常用的是Red-Black trees和AVL Trees,你应该从那里开始。
通过您的要求(我正在考虑这种情况,其中单词是键(索引),描述是该键指向的数据):
1. 我应该可以添加/删除单词 - 检查,您从树中添加和删除节点。
2.应该可以修改描述-检查,描述没有被索引,所以当你找到一个时,你可以用它做任何你想做的事情,而不用改变树本身。
3. 快速访问 - 检查,您有 log2(N) 访问权限,树保持平衡(因此 - 它是自平衡树)。
4. 一些描述可以是半空的 - 描述只是一个连接到节点的数据,它可以是空的,或者任何你喜欢的,不会改变结构内部的任何东西。
5.根据一些信息过滤单词 - 我没有得到这个,过滤的东西可以通过复制树来实现,但是没有你想要过滤的单词,因此你会得到另一棵树,它只有那些您想要的单词(并且描述不会被复制)。
编辑:您应该知道的一件事 - 很好地实现这些树并不是一件容易的事。很容易得到一两个错误,你应该在每一步检查你的实现的正确性。此外,如果您想更深入地了解更多结构,您可能需要阅读Knuth's。
【讨论】:
Ravadre 指出了基于搜索树的数据结构。
最大的选择是使用hash table。它相对于树的主要缺点是它内部的数据没有排序——元素的排序有些随意。如果您需要按排序顺序访问元素,则不建议使用哈希表。
但是,如果您确实不需要需要排序的项目,请使用哈希表:访问时间平均为 O(1),虽然这取决于很多因素,但通常仍然很远优于基于树的结构的访问时间。
顺便说一句,大多数编程语言已经提供了一种或两种数据结构,因此您无需自己实现它们。
【讨论】:
SortedList 和 SortedDictionary,这两者都是使用二叉搜索树实现的。
如果我理解正确,您想建立一个真正的字典,即包含描述、视频和图像的单词列表?并且不实现字典数据类型?
对于前者,我建议数据库是您的最佳选择。您不必将整个结构保存在内存中,良好的索引结构允许快速访问。 SQL 查询将使您能够按描述或任何其他字段进行过滤。
这种方法的主要缺点是插入算法,因为数据库增加了插入单词所需的时间(假设您不想保持顺序)会增加。对正确位置的二进制搜索可能是您最好的开始。显然,这促进了对二叉树结构的需求。
对于实际的数据库本身,有几种方法可以解决。将实际单词作为索引可能值得考虑,并且具有额外的优势,即您可以根据索引直接获得位置(假设您可以将字符串转换为随着单词位置增加而增加的数字
希望这会有所帮助。
【讨论】:
为了存储以单词为键的字典,您可能希望使用 trie,一种键通常是字符串的数据结构。挺好看的。
如果您将字典本身存储在一个数组中,则单词键映射到的值可能只是该单词出现在其描述中的数组中字典条目的索引列表。
如果您不想使用 trie:您可以使用哈希表或某种二叉树。
使用哈希表,理论上,查找速度非常快,但可能会发生冲突,这意味着性能可能会随着时间的推移而变差。另见this blog post。
使用平衡二叉搜索树(红黑树非常流行),键的查找可能会慢一些,但(如果使用平衡树)可以保证相对较好的性能。
【讨论】: