在另一个字符串中搜索字符串数组的最有效方法

时间:2012-03-06 13:41:11

标签: java arrays performance algorithm

我有一大堆字符串看起来像这样:     String temp [] = new String [200000]。

我有另一个字符串,我们称之为大文字。我需要做的是遍历temp的每个条目,检查是否在bigtext中找到该条目,然后根据它进行一些工作。所以,骨架代码看起来像这样:

for (int x = 0; x < temp.length; x++) {
  if (bigtext.indexOf(temp[x]) > -1 {

  //do some stuff
  } else continue;
}

因为temp中有很多条目,并且有很多bigtext实例,所以我想以最有效的方式做到这一点。我想知道如果有更好的方法可以做到这一点,我所概述的是最有效的方法来迭代搜索。

谢谢,

埃利奥特

8 个答案:

答案 0 :(得分:14)

我认为您正在寻找像Rabin-KarpAho–Corasick这样的算法,这些算法旨在并行搜索文本中的大量子字符串。

答案 1 :(得分:10)

请注意,您当前的复杂程度为O(|S1|*n),其中|S1|bigtext的长度,n是数组中元素的数量,因为每次搜索实际上都是O(|S1|)

通过bigtext 构建suffix tree并迭代数组中的元素,您可以将此复杂性降低到O(|S1| + |S2|*n),其中{{1}是数组中最长字符串的长度。假设|S2|,它可能会快得多!

构建后缀树的日期为|S2| << |S1|,每次搜索都为O(|S1|)。您不必通过O(|S2|)来查找它,只需在后缀树的相关部分上找到它。由于它完成了bigtext次,因此总共得到n,这比天真的实现更渐进。

答案 2 :(得分:8)

如果您有关于temp的其他信息,则可以改进迭代。

如果并行化迭代,您还可以减少花费的时间。

答案 3 :(得分:5)

效率在很大程度上取决于对你有价值的东西。

您是否愿意增加记忆以缩短时间?您是否愿意增加有效处理大型数据集的时间?您是否愿意增加对CPU内核的争用?您是否愿意进行预处理(可能是一种或多种索引形式)以减少关键部分的查找时间。

随着您的提供,您表明您想要的整个部分更有效,但这意味着您已经排除了可以进行权衡的代码或系统的任何部分。这迫使人们想象你关心什么以及你不关心什么。根据一个人的观点,所有发布的答案都是正确和不正确的赔率非常高。

答案 4 :(得分:3)

另一种方法是将文本标记化 - 让我们说用普通的标点符号来区分。然后将这些标记放入Set,然后找到与主容器的交叉点。

而不是数组,也可以在Set中保留单词。只需执行

即可计算交点
bidTextSet.retainAll(mainWordsSet);

{1}中出现的bigText中出现的字词仍然存在。

答案 5 :(得分:3)

使用像Boyer-Moore这样的搜索算法。 Google Boyer Moore,它有很多链接可以解释它是如何工作的。例如,有a Java example

答案 6 :(得分:2)

我担心它在任何情况下都没有效率!

要选择正确的算法,您需要提供一些答案:

  1. 可以离线计算什么?也就是说,提前知道bigText了吗?我想temp不是名字。
  2. 你真的在搜索单词吗?如果是,index themBloom filter也可以提供帮助。
  3. 如果你需要一点模糊性,可能干还是soundex可以做这个工作?
  4. 坚持严格包含测试,您可以从temp数组中构建trie。它会阻止多次搜索相同的子字符串。

答案 7 :(得分:1)

是一种非常有效的方法。您只需评估temp.length一次

即可稍微改善一下
for(int x = 0, len = temp.length; x < len; x++)

虽然您没有提供足够的程序细节,但很有可能您可以通过重新设计程序找到更有效的方法。