2015-07-21 81 views
4

搜索關鍵詞列表我有一個列表的關鍵字列表,我有數據從一些源來,這將是一個列表了。爪哇 - 在另一個字符串列表

我想找到如有關鍵字的數據列表中存在,如果是添加這些關鍵字,另一個目標列表。

E.g.

關鍵詞列表= FIRSTNAME, LASTNAME, CURRENCY & FUND

數據列表= HUSBANDFIRSTNAME, HUSBANDLASTNAME, WIFEFIRSTNAME, SOURCECURRENCY & CURRENCYRATE.

從上面的例子,我想作關鍵字FIRSTNAME, LASTNAME & CURRENCY目標列表,但FUND不應該來,因爲它沒有在數據中存在名單。

下面我有一個解決方案的工作原理是利用兩個for循環(一個在另一個內部),並檢查與字符串包含的方法,但我想,以避免兩個循環,尤其是一個在另一個內部。

for (int i=0; i<dataList.size();i++) { 
     for (int j=0; j<keywordsList.size();j++) { 
      if (dataList.get(i).contains(keywordsList.get(j))) { 
        targetSet.add(keywordsList.get(j)); 
        break; 
      } 
     } 
    } 

有沒有其他解決方案可以解決我的問題?

+0

怎麼樣'文獻Listener'這將取決於'String'匹配提取'JList的data'。通過幾個事件,你可以達到你想要的。我想這不復雜 – mustangDC

回答

1

下面是使用regex的單循環方法。您可以使用關鍵字構建模式,然後遍歷您的dataList並查看是否可以找到匹配項。

public static void main(String[] args) throws Exception { 
    List<String> keywords = new ArrayList(Arrays.asList("FIRSTNAME", "LASTNAME", "CURRENCY", "FUND")); 
    List<String> dataList = new ArrayList(Arrays.asList("HUSBANDFIRSTNAME", "HUSBANDLASTNAME", "WIFEFIRSTNAME", "SOURCECURRENCY", "CURRENCYRATE")); 
    Set<String> targetSet = new HashSet(); 

    String pattern = String.join("|", keywords); 
    for (String data : dataList) { 
     Matcher matcher = Pattern.compile(pattern).matcher(data); 
     if (matcher.find()) { 
      targetSet.add(matcher.group()); 
     } 
    } 

    System.out.println(targetSet); 
} 

結果:

[CURRENCY, LASTNAME, FIRSTNAME] 
+0

謝謝Shar1er80。我可能會繼續這個想法,因爲它看起來不錯,給我輸出我需要的,但是有點擔心,正則表達式可能不需要額外的處理時間? – vnkotak

1

嘗試阿霍Corasick算法。該算法可以獲得數據中每個關鍵字的出現次數(您只需要它是否出現)。

複雜度O(Sum(Length(Keyword)) + Length(Data) + Count(number of match))

這裏是wiki-page

在計算機科學中,阿霍Corasick算法是一個字符串搜索 算法由Alfred V.阿霍和Margaret J. Corasick發明的。它是 一種字典匹配算法,它在輸入文本中查找有限字符串集合(「字典」)的元素。它 同時匹配所有模式。算法 的複雜度在模式長度加上搜索文本的長度加上輸出匹配的數量上是線性的。

對於類似的情況,我在幾年前實現了它(大約200行),它運行良好。

如果你只關心關鍵詞出現與否,你可以修改算法的情況下具有更好的複雜性:

O(Sum(Length(Keyword)) + Length(Data))

你可以找到來自互聯網實現該算法的無處不在,但我認爲這是很好的爲你明白,算法和實現它自己。


編輯:

我想你想消除雙迴路,所以我們需要找到所有的關鍵詞在一個循環。我們稱之爲Set Match Problem,即一組模式(關鍵字)匹配文本(數據)。你想解決Set Match Problem,那麼你應該選擇Aho–Corasick algorithm這是特別爲這種情況下設計的。這樣,我們將得到一個循環解決方案:

for (int i=0; i < dataList.size(); i++) {  
    targetSet.addAll(Ac.run(keywordsList)); 
} 

您可以從here找到一個實現。

+0

謝謝Sayakiss。欣賞你的想法。我快速查看了算法,它可能適用於我的問題,但坦率地說,對於一個簡單的問題,解決方案將變得複雜。我的意思是,雖然兩個for循環的解決方案只需少於10行代碼,但實現算法需要付出很多努力。我很期待能夠節省處理時間的解決方案,並且可以在更短的時間內實施。 :) – vnkotak

+0

@vnkotak在答案中看到我的編輯。 – Sayakiss

+0

謝謝Sayakiss。它看起來很好。 – vnkotak