O(m+n) 的字符匹配,其中m是字符串的长度,n是匹配串的长度
Next数组预处理
性质: (i+1)-Next[i] 即前缀的长度减去对应的Next为前缀循环节的大小
string pattern; //模式子串
vector<int> Next(pattern.length(),0); //Next数组
void Next_pre(string p,vector<int> &Next)
{
for(int i=1,j=0;i<(int)p.length();i++) //i是当前遍历到的后缀 j是前缀
{
while(j&&p[i]!=p[j])j=Next[j-1]; //跳转
if(p[i]==p[j])j++; //前后缀一样 前缀开始向后
Next[i]=j;
}
}
匹配
string s; //待匹配字符串
string pattern; //模式子串
int KMP_match(string s,string p,int begin) //返回的是匹配成功的索引起点
{
vector<int> Next(p.length(),0);
Next_pre(p,Next); //预处理出跳转数组
for(int i=begin,j=0;i<(int)s.length();i++)
{
while(j&&s[i]!=p[j])j=Next[j-1]; //当前匹配失败 跳转
if(s[i]==p[j])j++; //匹配成功 进行一下个
if(j==(int)p.length())
{
//j=Next[j-1]; //有需要的话继续下一次匹配
//匹配成功后的操作
return i-(int)p.length()+1; //返回在s中匹配到的下标
}
}
return -1; //匹配不成功
}