【问题标题】:Algorithm to compare a list of word String to a list of regular expression将单词字符串列表与正则表达式列表进行比较的算法
【发布时间】:2014-08-13 02:21:41
【问题描述】:

我想从 expList 中统计 textToBeTested 数组中是否存在单词。

请注意,expList 和 textToBeTested 数组都可以非常大。

我可以简单地遍历两个列表并使用“.matches”方法进行计数,但它在 O(n^2) 中。

我可以使用任何更快的算法或实现吗?

    String[] expList = {"i", "i'd", "i'll", "i'm", "i'm", "bet[a-zA-Z]*", "my[a-zA-Z]*"};
    String[] textToBeTested = {"this", "is", "better", "than", "my", "method"};

例如在上面的 textToBeTested 数组中,"better" 和 "my" 匹配 expList 数组中的一个字符串,所以它会返回 2。

非常感谢您的帮助。

【问题讨论】:

    标签: java regex algorithm arraylist


    【解决方案1】:

    将所有模式编译成使用交替的更大模式怎么样?如果正确编译到状态机中,交替可以很快(如 Aho Corasick 或 KMP)。

    boolean first = true;
    StringBuilder sb = new StringBuilder();
    for (String s : expList) {
        sp.append("(?:").append(Pattern.quote(s)).append(')');
        if (!first) {
            sb.append('|');
        }
        first = false;
    }
    
    Pattern pattern = Pattern.compile(sb.toString());
    
    // Possibly make this a ForkJoinTask
    int count = 0;
    for (String s : textToBeTested) {
        if (pattern.matcher(s).matches()) {
            count++;
        }
    }
    

    【讨论】:

    • @user3286982 是的。您基本上要求的是 Aho Corasick 泛化为正则表达式。这基本上就是你这样做的方式。现在,我很好奇性能比较。
    • 性能神奇地提高了。您的方法将问题从 O(n^2) 减少到 O(n),这有助于提高性能。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 1970-01-01
    相关资源
    最近更新 更多