KMP修改 - 在字符串中搜索简单模板匹配

时间:2014-04-09 16:17:46

标签: string algorithm knuth-morris-pratt

我想找到字符串S中与正则表达式R匹配的所有子字符串。正则表达式只能包含'。'和符号(其中'。'表示任何符号)。我正在尝试用KMP来解决这个问题:

1)构建字符串T = R +'#'+ S('#'在这里是分隔符)

2)计算prefix-func。对于T

3)对于pi(T的前缀-func。)检查'#'之后的位置,其中pi [i] == len(S)。在这些寻求子串结束的位置。

但是前缀-func。无法在带有'。'的字符串上正常工作我的前缀为func。的代码:

pi[0] = 0;
for (int j = 0, i = 1; i < R.length(); i++) {
    while (j > 0 && s[i] != s[j] && s[i] != '.' && s[j] != '.' || s[i] == '#' || s[j] == '#')
        j = pi[j - 1];
        if (s[i] == s[j] || (s[i] == '.' && s[i] != '#') || (s[j] == '.' && s[j] != '#'))
            j++;
        pi[i] = j;
}

在测试S =“abab”时失败,T =“a。”。

我知道可以使用KMP解决这个问题,你能告诉我怎么做吗?

2 个答案:

答案 0 :(得分:1)

参见http://homepage.usask.ca/~ctl271/810/approximate_matching.shtml,其中导出了基于后缀树的算法,以找出长度为m的模式P的所有出现,其中k个通配符在O(kn)时间内的长度为n的字符串中,对于k&lt; ;&LT;通过检查长度为m的所有子串来获得匹配,m可以比天真的O(nm)时间好得多。

答案 1 :(得分:0)

我不知道KMP的修改处理了无关的符号。您可以构建一个确定性的字符串匹配自动机,或者可以在连续的非无关符号上使用Aho-Corasick变体。我不知道如何证明这两种情况中最坏的情况。

来自SODA 2002的Adam Kalai的one-pager讨论了一个非常简单的基于FFT的方法来解决这个问题。如果最坏情况的复杂性很重要,我可能会建议使用它。