什么是最好的自动完成/建议算法,数据结构 [C++/C]

Posted

技术标签:

【中文标题】什么是最好的自动完成/建议算法,数据结构 [C++/C]【英文标题】:What is the best autocomplete/suggest algorithm,datastructure [C++/C] 【发布时间】:2010-12-19 12:17:13 【问题描述】:

我们看到 Google、Firefox 的一些 AJAX 页面在用户键入字符时显示可能的项目列表。

谁能给出一个好的算法,实现自动完成的数据结构?

【问题讨论】:

【参考方案1】:

对于大型数据集,后端的一个很好的候选者是三元搜索树。它们结合了两个方面的优点:二叉搜索树的低空间开销和数字搜索尝试的基于字符的时间效率。

参见 Dobbs 博士杂志:http://www.ddj.com/windows/184410528

目标是在用户输入时快速检索有限的结果集。让我们首先考虑搜索“计算机科学”,您可以从“计算机”或“科学”开始输入,但不能从“计算机”开始输入。因此,给定一个短语,生成以单词开头的子短语。现在对于每个短语,将它们输入 TST(三元搜索树)。 TST 中的每个节点都将表示到目前为止已键入的短语的前缀。我们将在该节点中存储该前缀的最佳 10 个(比如说)结果。如果一个节点的候选结果多于有限数量的结果(此处为 10 个),则应该有一个排名函数来解决两个结果之间的竞争。

树可以每隔几个小时构建一次,具体取决于数据的动态性。如果数据是实时的,那么我想其他一些算法会提供更好的平衡。在这种情况下,绝对要求是对每次键入的击键都进行闪电般的快速检索结果,这非常好。

如果涉及拼写更正的建议,将会出现更多的复杂情况。在这种情况下,还必须考虑编辑距离算法。

对于像国家列表这样的小型数据集,Trie 的简单实现就可以了。如果您要在 Web 应用程序中实现这样的自动完成下拉菜单,则在您提供列表中的数据后,YUI3 的自动完成小部件将为您完成所有工作。如果您将 YUI3 仅用作大数据支持的自动完成的前端,请在 C++ 中制作基于 TST 的 Web 服务,然后使用自动完成小部件的脚本节点数据源从 Web 服务中获取数据,而不是简单的列表。

【讨论】:

【参考方案2】:

trie 是一种数据结构,可用于快速查找与前缀匹配的单词。

编辑:这是一个示例,展示如何使用一个来实现自动完成http://rmandvikar.blogspot.com/2008/10/trie-examples.html

这是 3 个不同的auto-complete implementations 的比较(尽管它是在 Java 中而不是 C++ 中)。

* In-Memory Trie
* In-Memory Relational Database
* Java Set

在查找键时,trie 比 Set 实现要快一些。 trie 和 set 都比关系数据库解决方案快很多。

Set 的设置成本低于 Trie 或 DB 解决方案。您必须决定是否经常构建新的“词集”,或者查找速度是否是更高的优先级。

这些结果在 Java 中,您的里程可能会因 C++ 解决方案而异。

【讨论】:

有点相关的是 Google 的 Peter Norvig 对如何进行拼写更正的描述:norvig.com/spell-correct.html 标准 Trie 非常占用内存,对于较大的集合,您想使用 Compacted Trie,从而大大减少内存占用。其他优化包括节点值的延迟初始化和子/值集的正确数据结构。不久前,我创建了一个 autocomplete library 能够处理非常大的数据集(10,000,000+)并有效地回答精确和近似搜索。【参考方案3】:

Segment trees可用于高效实现auto complete

【讨论】:

【参考方案4】:

如果您想建议最受欢迎的完成,“建议树”可能是一个不错的选择: Suggest Tree

【讨论】:

【参考方案5】:

对于一个简单的解决方案:您生成一个具有最小编辑 (Levenshtein) 距离(1 或 2)的“候选人”,然后使用哈希容器(set对于一个简单的解决方案就足够了,然后使用 tr1 或 boost 中的 unordered_set

示例: 你写了卡尔,你想要汽车。 arr 由 1 次删除生成。 arr 在您的 unordered_set 中吗?编号 crr 由 1 次删除生成。 crr 在您的 unordered_set 中吗?车号是1次删除生成的。 car 在你的 unordered_set 中吗?是的,你赢了。

当然还有插入、删除、转置等……

您发现生成候选者的算法确实是在浪费时间,尤其是当您的 unordered_set 非常少时。

【讨论】:

以上是关于什么是最好的自动完成/建议算法,数据结构 [C++/C]的主要内容,如果未能解决你的问题,请参考以下文章

建议收藏!10 种 Python 聚类算法完整操作示例

c++最好的开发工具

C++编程除了编程知识还要知道啥东西。也可以是C++有理论变现实需要啥东西,比如数据库,具体要学啥

最好的自动换行算法? [关闭]

自动完成算法?

C++寻路算法