“包含字符串”的快速索引

时间:2010-01-18 10:58:29

标签: c++ algorithm stl

在我的应用程序中,我有数百万个短字符串(大多数短于32个字符)。我想实现一个带有附加列表的搜索框,该列表仅包含包含在搜索框中输入的整个字符串的元素。我怎样才能预建一个索引来快速找到这样的字符串?所有已排序的STL容器都会检查整个字符串。

对于输入的搜索字符串“str”,我需要找到所有包含“str”的字符串:“main street”,“struve”,“ustr”等。

6 个答案:

答案 0 :(得分:7)

您可以构建Permuterm indexes

对于“struve”,您将插入Radix tree(或通用搜索树):

struve$
truve$s
ruve$st
uve$str
ve$stru
e$struv
$struve

要搜索中缀,您将从根节点搜索匹配的前缀字符串。

答案 1 :(得分:3)

您可以先查看trie's。虽然它们主要用作前缀树,但数据结构本身可能适用于更快的一般搜索。

答案 2 :(得分:2)

如果字符串具有任意长度和任意计数,您可以尝试Aho-Corasick算法,该算法易于实现并在搜索文本长度的O(n)处进行缩放,并执行同时搜索所有字符串。

或者,如果您要查找的字符串数量很少,请尝试Horspool算法,这种算法非常容易实现,平均每个字符串少于O(n)

答案 3 :(得分:1)

你说你有数百万的短字符串,所以我假设你不能存储它并将它保存在数据库中。 假设您在名为my_string(id,string)的表中保留“短字符串”。 创建另一个表,让我们将其命名为my_substring(id,substring [unique]),包含my_string中每个字符串的每个子字符串。 还为上面的两个表创建一个连接表:my_substring_to_string(id,substring_id,string_id),我猜想其内容很明显。

现在搜索非常简单快捷:在my_substring中搜索你的子字符串(记得在my_substring.substring上创建一个索引)并通过my_substring_to_string将它与my_string连接。

添加和删除新的短字符串需要在my_substring和my_substring_to_string中进行更新,但这些都非常简单。

如果此解决方案将生成具有不可接受的大尺寸的my_substring表,则可以对其进行优化。而不是保持每个子字符串尝试保留每个后缀并使用ilike搜索'substring%'。 例如,如果单词是'blues',则必须存储后缀: 'blues','lues','ues','es','s'(加上'蓝调')。然后搜索'lu'(ilike'lu%')将匹配'lues'。这样,数据库仍然可以使用在my_substring.substring列上创建的索引,因此搜索仍然很快。

答案 4 :(得分:0)

我会使用SQLite。也许在内存中使用数据库,无论如何你在RAM中加载所有内容并需要极端性能。

答案 5 :(得分:0)

我可能从反向索引开始 - 即一个字母列表,并附加到每个包含该字母的单词列表。如果您只使用字母(特别是如果您将其限制为英语,或至少是西欧语言),您还可以非常轻松地为有向图(即每对字母),三字母等创建反向索引 - 虽然远远超过三字母可能不会获得很多,因为到那时你通常会将列表缩小到可以很容易地在列表中进行正常字符串搜索的程度。

请注意,我并不打算将“list”表示“链表”,而只是“某种顺序数据结构”,这通常意味着一个向量......