有效地搜索大型字符串列表

时间:2012-05-02 21:00:19

标签: string algorithm search

我有一个很大的字符串列表,需要由iPhone / Android应用程序的用户搜索。字符串按字母顺序排序,但实际上并没有那么有用,因为如果搜索查询落在字符串内的任何位置,而不仅仅是开头,则字符串应包含在结果中。当用户键入其搜索查询时,应更新搜索以反映他们当前输入的结果。 (例如,如果他们输入“cat”,它应该在键入时显示“c”,“ca”和“cat”的结果。)

我目前的做法如下:

我有一堆“搜索结果”,它开始是空的。如果用户键入某些内容以使搜索查询更长,我将当前搜索结果推送到堆栈,然后仅搜索当前搜索结果中的新搜索结果(某些内容不可能出现在完整的字符串列表中但不是当前的结果在这种情况下)。

如果用户点击退格,我只需要从堆栈中弹出搜索结果并恢复它们。这几乎可以立即完成。

此方法适用于“向后”搜索(使搜索查询更短)以及搜索查询已经足够长以使结果数量较少的情况。但是,它仍然必须在O(n)时间内搜索用户键入的前几个字母中的每个字母的完整字符串列表,这非常慢。

我考虑过的一种方法是预先编译所有可能的2或3个字母的搜索查询结果列表。这种方法的问题在于它需要26 ^ 2或26 ^ 3这样的列表,并且会占用相当大的空间。

您能想到的任何其他优化或替代方法?

3 个答案:

答案 0 :(得分:4)

您应该考虑使用prefix tree (trie)制作预先计算的列表。我不确定在子字符的基础上显示'c','ca'和'cat'的结果是一个好主意。例如,假设用户正在搜索“吃”这个词。你的算法必须找到包含'e',然后是'ea',最后是'eat'的所有单词;其中大部分对用户没用。对于手机应用程序,如果你在一个单词的基础上做它可能会更好。多字符串可以被标记化,因此在“大量赌注”中搜索“赌注”将正常工作,但不会搜索“拍摄”。

答案 1 :(得分:1)

我注意到,当我只按下1或2个字符时,谷歌和其他人都没有提供完整列表。在您的情况下,可能一个好的起点是仅在用户键入至少3个字符时才开始填充搜索查询结果。

对于更高版本,如果它很重要,您可以从Google的方式中获取提示,并进行更复杂的处理:跟踪以前用户选择的实际条目,并按频率对这些条目进行排序。然后,每天在服务器上运行一个cron作业,填充一个小数据库表,其中前10个条目以每个字母开头,如果只按下了1或2个字母,则使用此小表中的结果而不是扫描完整列表。

答案 2 :(得分:1)

您可以使用压缩后缀树