2015-07-21 49 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