Java - 在另一个字符串列表中搜索关键字列表

时间:2015-07-21 05:35:08

标签: java algorithm list loops

我在列表中有一个关键字列表,我有来自某些来源的数据,这也是一个列表。

我想查找数据列表中是否存在任何关键字,如果是,则将这些关键字添加到另一个目标列表。

E.g。

关键字列表= SDK manager

数据列表= FIRSTNAME, LASTNAME, CURRENCY & FUND

从上面的示例中,我想制作一个包含关键字HUSBANDFIRSTNAME, HUSBANDLASTNAME, WIFEFIRSTNAME, SOURCECURRENCY & CURRENCYRATE.的目标列表,但FIRSTNAME, LASTNAME & CURRENCY不应该出现,因为它不存在于数据列表中。

我在下面有一个解决方案,通过使用两个for循环(一个在另一个内部)并使用String contains方法检查,但我想避免两个循环,尤其是一个在另一个循环中。

FUND

我的问题还有其他替代解决方案吗?

2 个答案:

答案 0 :(得分:1)

尝试Aho-Corasick算法。该算法可以得到数据中每个关键字的出现次数(只需要它是否出现)。

复杂性为O(Sum(Length(Keyword)) + Length(Data) + Count(number of match))

以下是wiki-page

  

在计算机科学中,Aho-Corasick算法是一个字符串搜索   由Alfred V. Aho和Margaret J. Corasick发明的算法。它是   一种字典匹配算法,用于定位a的元素   输入文本中的有限字符串集("字典")。它   同时匹配所有模式。算法的复杂性   是模式的长度加上长度的线性   搜索文本加上输出匹配的数量。

我在几年前就类似的情况实施了它(大约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找到实施。

答案 1 :(得分: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]