高效的字符串文本搜索

时间:2013-07-31 11:35:06

标签: java

我想创建一个搜索一小段文本(通常不超过256个字符)的方法,以存在大约20个不同单词中的任何一个。如果它在文本中找到一个,无论大小写都返回true。

该方法将执行相当多(不是疯狂的数量),因此它必须尽可能高效。你觉得这里最好的是什么?

这20个字不会改变。它们是静态的。但要扫描的文本确实如此。

8 个答案:

答案 0 :(得分:5)

我建议:将输入文本中的所有字词添加到Set - 毕竟只有256个字符,添加它们是O(n)操作。

之后,您可以使用contains() Set的{​​{1}}操作测试20个左右的会员单元中的每一个,这是O(1)

答案 1 :(得分:3)

由于要搜索的20个单词不会更改,因此查找它们的最快方法之一是编译与它们匹配的正则表达式,并在不同的输入上重复使用它。将正则表达式与给定字符串匹配的复杂性与不需要回溯的简单正则表达式的字符串长度成线性关系。在你的情况下,长度是有界的,所以它是O(1)。

答案 2 :(得分:2)

String类已经有很多方法可以做这些事情。例如,indexOf方法将解决您的问题:

String str = "blahblahtestblah";
int result = str.indexOf("test");
如果字符串不包含单词“test”,则

result将包含-1。我不确定这对你来说是否足够有效,但我会从这里开始,因为它已经实现了!

答案 3 :(得分:2)

假设这20个单词位于Set<String>且全部为小写,那么就像以下一样简单:

public final boolean containsWord(final String input)
{
    final String s = input.toLowerCase();
    for (final String word: wordSet)
        if (s.indexOf(word) != -1)
            return true;
    return false;
}

答案 4 :(得分:1)

如果您想同时搜索多个不同的目标,那么Rabin-Karp algorithm是可能的。如果在20个目标列表中只有几个不同的单词长度,则效率特别高。一次通过字符串将找到给定长度的所有匹配。

答案 5 :(得分:0)

我会做以下事情:

String longStr //the string to search into
ArrayList<String> words; //the words to check

Iterator<String> iter = words.iterator();
while(iter.hasNext())
{
    if(longStr.contains(iter.next()))
        return true;    
}
return false;

答案 6 :(得分:0)

您可以将所有单词添加到列表中,对其进行排序并使用Collections.binarySearch(...)。排序时会松动,但binarySearch是log(n)。

答案 7 :(得分:0)

确定。感谢您回答和评论每个人。我意识到我提出的问题可以有广泛而多样的答案。但这就是我最终使用的原因,因为性能非常重要,因此使用标准集合不会削减芥末。

我使用了“Patricia Trie”结构,这是一种非常强大而优雅的数据结构,能够提供低内存开销和极快的搜索速度。

如果有人有兴趣,可以video here简要解释一下Patricia Trie是如何运作的。你会意识到为什么看完后它会如此高效。此外,github here上还有一个数据结构的Java实现。