功能
- 在主串中查找子串,返回头位置(0开头索引)
复杂度
- n,m为主串和子串长度
思路
- 把主串和子串拼接到一起,中间隔开,记为合并串s
- 对s中的每一个子串计算其最长匹配真前后缀长度,如果有某一个字串的最长匹配真前后缀长度等于子串长度,则说明查找到子串
- 对于每一个子串希望求他的最长匹配真前后缀长度,他的最长匹配前后缀长度等于他去掉末尾的子串s'匹配上的长度
代码
void kmp(string &s1,string &s2){
int m=s2.size();
s2=s2+'#'+s1;
int n=s2.size();
vector<int>p(n);
for(int i=1;i<n;i++){
int len =p[i-1];
while(len&&s2[i]!=s2[len]){
len=p[len-1];
}//找第一个能匹配上最后一位的子串
if(s2[i]==s2[len]){
p[i]=len+1;//找到了就更新len
if(p[i]==m){
return i-m*2+1;//去除偏移量
}
}
}
return -1;
}