簡體   English   中英

在另一個字符串中搜索字符串數組的最有效方法

[英]The most efficient way to search for an array of strings in another string

我有一大堆字符串,看起來像這樣:String temp [] = new String [200000]。

我有另一個字符串,讓我們稱它為bigtext。 我需要做的是遍歷temp的每個條目,檢查是否在bigtext中找到該條目,然后根據它進行一些工作。 所以,骨架代碼看起來像這樣:

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

  //do some stuff
  } else continue;
}

因為temp中有很多條目,並且有很多bigtext實例,所以我想以最有效的方式做到這一點。 我想知道如果有更好的方法可以做到這一點,我所概述的是最有效的方法來迭代搜索。

謝謝,

埃利奧特

我認為你正在尋找一種像Rabin-KarpAho-Corasick這樣的算法,它們可以並行搜索文本中的大量子字符串。

請注意,您當前的復雜度為O(|S1|*n) ,其中|S1| bigtext的長度, n是數組中元素的數量,因為每次搜索實際上都是O(|S1|)

通過bigtext構建后綴樹 ,並迭代數組中的元素,可以將這種復雜性降低到O(|S1| + |S2|*n) ,其中|S2| 是數組中最長字符串的長度。 假設|S2| << |S1| |S2| << |S1| ,它可能會快得多!

構建后綴樹是O(|S1|) ,每次搜索都是O(|S2|) 您不必通過bigtext來查找它,只需要在后綴樹的相關部分上找到它。 由於它完成了n次,你得到的總數為O(|S1| + n*|S2|) ,這比天真的實現更漸進。

如果您有關於temp其他信息,您可以改進迭代。

如果並行化迭代,還可以減少花費的時間。

效率在很大程度上取決於對您有價值的東西。

你是否願意增加記憶以縮短時間? 您是否願意增加有效處理大型數據集的時間? 您是否願意增加對CPU內核的爭用? 您是否願意進行預處理(可能是一種或多種形式的索引)以減少關鍵部分的查找時間。

隨着您的提供,您指出您想要的整個部分更有效,但這意味着您已經排除了可以進行權衡的代碼或系統的任何部分。 這迫使人們想象你關心什么以及你不關心什么。 根據一個人的觀點,所有發布的答案都是正確和不正確的賠率非常高。

另一種方法是將文本標記化 - 讓我們說用普通的標點符號來區分。 然后將這些標記放入Set ,然后找到與主容器的交叉點。

不要使用數組,也要在Set保留單詞。 可以通過簡單地計算交點

bidTextSet.retainAll(mainWordsSet);

剩下的將是你的“詞典”中bigText中出現的詞。

使用像Boyer-Moore這樣的搜索算法。 Google Boyer Moore,它有很多鏈接可以解釋它是如何工作的。 例如,有一個Java示例

我擔心它在任何情況下都沒有效率!

要選擇正確的算法,您需要提供一些答案:

  1. 可以離線計算什么? 那就是提前知道bigText嗎? 從它的名字來看,我想temp不是。
  2. 你在搜索單詞嗎? 如果是,請索引它們 布隆過濾器也可以提供幫助。
  3. 如果你需要一點模糊性,可能干或soundex可以做這個工作?

堅持嚴格包含測試,您可以從temp數組中構建一個trie 它會阻止多次搜索相同的子字符串。

一種非常有效的方法。 您只需評估一次temp.length就可以略微改善它

for(int x = 0, len = temp.length; x < len; x++)

雖然您沒有提供足夠的程序細節,但很有可能您可以通過重新設計程序找到更有效的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM