对字符串列表进行近似搜索

时间:2011-06-27 05:38:46

标签: java algorithm string java-me

所以是的,我读到了如何在字符串之间使用编辑距离来决定“关闭”两个字符串是如何相互关联的。该算法作为动态问题实现需要O(mn)时间,其中m和n分别是文本和模式的长度。因此,如果我必须将一个字符串与5000多个其他字符串匹配,那将花费很多时间,这在我的应用程序上根本不可接受。是否有更快的解决方案可以实施?我不介意交易存储空间的时间。

我在Android上看过一个名为“Swype”的应用程序,它做了类似的事情。它会根据自己的数据库搜索您的查询并建议结果。这怎么快这么快?

注意:请不要建议像Lucene这样的框架,因为我无法在J2ME上运行。

4 个答案:

答案 0 :(得分:2)

splix的答案很好。作为另一种选择(对于非常大的字符串集),您可能需要考虑使用n-gram表示:

http://en.wikipedia.org/wiki/N-gram

这些用于许多数据库包中的近似模式匹配,因为它们使用传统的索引方法快速且易于实现。

答案 1 :(得分:1)

我们曾使用http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm几乎相同的东西,它对我们来说很好。

它的Java实现很少,你可以在网上找到它们

PS你也可以检查其他字符串匹配算法:http://en.wikipedia.org/wiki/String_searching_algorithm

答案 2 :(得分:1)

这实际上取决于您所比较的文本。在下文中,我将介绍原始编辑距离框架内的两个加速程序。

我们曾经有过相同的任务,我们将一个短词序列(类似于10-30个字符)与一个> 300k短句(每个也有10-30个字符)的字典组合在一起。在这种情况下,以下方法为我们节省了大量时间:

  • 对目标字符串的字典进行排序(这只需要进行一次)
  • 当您构建字符串i的n * m表时,您可以重用字符串i-1中的表,因为大多数行是共同的。

E.g。如果您有两个字符串"list of strings"和下一个"list of words",则可以重复使用表格的前8行,只需重新计算5(两个字符串共有8个字符)。这样,我们只需对代码进行少量更改即可节省高达70-80%的运行时间。

如果你没有长篇文章,第一种方法不会为你节省太多。但在这种情况下,您希望只有少数条目具有较小的编辑距离,而所有其他条目具有较大的距离。由于n * m表在每个方向上都是单调的(即每行的最小值是单调的,以及每列的最小值),因此一旦达到预先指定的阈值,就可以停止计算。如果在初始阈值内找不到解决方案,您甚至可以保存中间结果并“重新启动”计算(具有更高的界限)。

答案 3 :(得分:0)

它也是你如何定义“关闭”的问题。如果你不是坚持写作,但口语也会奏效,我可以建议soundex。它是一个非常快速的算法,用于查看2个单词是否为拼音关闭。