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

String KMP修改-搜索字符串中的简单模板匹配,string,algorithm,knuth-morris-pratt,String,Algorithm,Knuth Morris Pratt,我想查找字符串S中与正则表达式R匹配的所有子字符串。正则表达式只能包含“.”和符号(其中“.”表示任何符号)。我试图用KMP来解决这个问题: 1) 构建字符串T=R+'#'+S('#'在这里是除沫器) 2) 计算前缀func。对于T 3) 对于pi(T的前缀函数),检查“#”之后的位置,其中pi[i]==len(S)。在这些位置上寻找子串端 但是前缀func。无法在前缀为func的代码为“.”的字符串上正常工作: pi[0] = 0; for (int j = 0, i = 1; i <

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

1) 构建字符串T=R+'#'+S('#'在这里是除沫器)

2) 计算前缀func。对于T

3) 对于pi(T的前缀函数),检查“#”之后的位置,其中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;
}
pi[0]=0;
对于(int j=0,i=1;i0&&s[i]!=s[j]&&s[i]!='.&&s[j]!='.|s[i]='.| s[j]='.|
j=pi[j-1];
如果(s[i]==s[j]| |(s[i]='.&s[i]!='|')| |(s[j]='.&s[j]!='|')
j++;
pi[i]=j;
}
它在测试S=“abab”,T=“a.”时失败


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

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


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

请参阅从何处导出基于后缀树的算法,以查找长度为m的模式p的所有出现情况,其中k个通配符位于长度为n的字符串中,时间为O(kn),对于k,另一个最大字长的模式选项是Shift或aka bitap,例如-我认为您可以修改位掩码表以考虑不关心。