我有一大堆字符串看起来像这样: 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实例,所以我想以最有效的方式做到这一点。我想知道如果有更好的方法可以做到这一点,我所概述的是最有效的方法来迭代搜索。
谢谢,
埃利奥特
答案 0 :(得分:14)
我认为您正在寻找像Rabin-Karp或Aho–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)
我担心它在任何情况下都没有效率!
要选择正确的算法,您需要提供一些答案:
bigText
了吗?我想temp
不是名字。坚持严格包含测试,您可以从temp
数组中构建trie。它会阻止多次搜索相同的子字符串。
答案 7 :(得分:1)
是一种非常有效的方法。您只需评估temp.length
一次
for(int x = 0, len = temp.length; x < len; x++)
虽然您没有提供足够的程序细节,但很有可能您可以通过重新设计程序找到更有效的方法。