2014-01-14 150 views
1

是否有任何快速算法在字符串的Arraylist中搜索特定的字符串?搜索一組字符串包含Java中的ArrayList中的特定字符串

例如:

我有一個ArrayList:

{"white house","yellow house","black door","house in heaven","wife"} 

而想要搜索字符串包含 「家」。 它應該在最短時間內返回{"white house","yellow house","house in heaven"}。 我的意思是我的問題是處理沒有索引的大數據(大約167000個字符串的列表)。

謝謝!

+3

*「但在最短的時間內」*無論你做什麼,這將是O(n) –

+0

真正加快它的唯一方法是按字符數或最大的單詞對列表進行排序。那麼你可以忽略所有字符少的字符,比如「老婆」。否則,你真的不能做太多事情。您可以更快地搜索數字列表的唯一原因是因爲它們很容易訂購。沒有簡單的方法來訂購你的清單。 – BobbyD17

+0

@ BobbyD17我敢打賭,我可以通過一個線程池加速它;)(這並不會改變複雜性,請介意) –

回答

1

有兩個答案你的問題,這取決於你是否打算運行多個查詢或不:如果你只需要運行一次查詢

  • ,你的運氣了:你必須搜索整個數組從開始到結束。
  • 如果您需要運行大量查詢,則可以通過構建索引來減少工作量。

製作一個數據結構Map<String,List<String>>,通過你的List<String>中的字符串,並將它們拆分成單詞。對於令牌列表中的每個單詞,將原始字符串添加到相應的列表中。

此操作運行於O(N*W),其中N是長字符串的數量,W是每個字符串的平均字數。有了這樣的地圖,您可以在O(1)中運行查詢。

請注意,只有當查詢次數明顯超過每個字符串中的平均字數時,此方法才能獲得回報。例如,如果您的字符串平均有十個字,並且您需要運行五到八個查詢,則線性搜索會更快。

+0

謝謝,最後我編制了用於搜索的數組列表。 –

1

我同意Josh Engelsma。重複列表並逐一檢查是最簡單的方法。並且167000實際上不是一個非常大的數據,除非列表中的每個字符串都很長。在正常的PC中,班輪搜索算法只需幾秒鐘即可完成。

考慮編碼約定,代碼可能是這樣的:

for(String s : list) { 
    if(s.contains.("house")) { 
     //do sth. 
    } 
} 

如果搜索將不同的關鍵字相同的列表上進行了很多次,你可以建立一個反向索引,以加快搜索。

在您的例子:

{"white house","yellow house","black door","house in heaven","wife"} 

你可以預先處理的列表,每個句子分成詞,並建立類似的索引:

"house" --> {0,1,3} 
"white" --> {0} 
"yellow" --> {1} 
... 

這意味着「房子」被包含在列表中的第0,1和3個元素,依此類推。該索引可以用HashMap實現:

Map<String, LinkedList<Integer>> = new HashMap<String, LinkedList<Integer>>(); 

而且搜索操作在理想情況下將加速到O(1)複雜度。