使用Knuth-Morris-Pratt算法查找不同的子字符串

时间:2016-12-11 15:47:57

标签: java string algorithm pattern-matching

我只是学习KMP字符串匹配算法来查找给定字符串中的模式总出现率。我的部分代码如下所示,在java中实现:

void kmpMatcher( string text, string pattern) {
    int counter = 0;
    int n=text.length();
    int m=pattern.length();
    int [] pi = computePrefix(); // computes the prefix array
    int q = 0;
    for (int i=0;i<n;i++) {
        while(q > 0 && pattern.charAt(q) != text.charAt(i)) q = pi[q-1];
        if (pattern.charAt(q) == text.charAt(i)) q++;
        if (q==m) {
            out.println(i-m+1);
            q = pi[q-1];
            counter++;
        }
    }
    out.println("Total matches: " + counter);
} 

有没有办法使用上面的函数找到给定输入文本字符串中不同子字符串的总数?找到不同子字符串的逻辑是什么?

1 个答案:

答案 0 :(得分:0)

你可以在O(N^2)时间内完成(这比将所有子字符串添加到例如哈希表的天真解决方案更好):

  1. 让迭代遍历字符串S的所有内容。

  2. 对于字符串的每个后缀T,我们可以构建一个T#S字符串并为其计算前缀函数。

  3. 通过查看前缀函数数组并找到最大的T,我们可以找到前缀为p[i]且不是任何后缀的前缀的子串数。 i - p[i] < j,其中j是此后缀的第一个字符。

  4. 现在我们只需要在所有足够的时间内总结这些子串的数量。

  5. 如果您需要更快的解决方案(类似O(N)O(N log N)),您可以使用后缀结构(例如后缀自动机或后缀数组),但这些解决方案更复杂。