总结
1.kmp
kmp是一种字符串匹配的算法,普通的字符串匹配需要时间O(n*m) 。n:字符串长度 m:模版串长度,kmp算法通过对模版串进行预处理来找到每个位置的后缀和第一个字母的前缀的最大公共长度,可以让复制度降低到O(n+m)。
下面为kmp的模板
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int nxt[N];
int n,m;
int s[N];
int t[N];
void getnxt() //求子串的next数组 最大前后缀
{
int i=1;
int j=0;
memset(nxt,0,sizeof(nxt));
while(i<m) { //当然在未出现相等之前都nxt都赋予0
if(t[j]==t[i]) { //j是第一位 ,i从第二位开始 ,如果相等了,说明出现了相同前后缀
nxt[i] = ++j; //然后开始next数组 先记录i,然后i,j都++
i++; //第i位若相等的话就应该是已经存在相同前后缀了,故先+1->++j;
}
else if(!j) { //j=0,i++往后挪
i++; //当有一次相等的话,该条件就不会存在了
}
else { // 123124 eg: 此时到a[5] nxt[4]=2 检索a[5]时 i=5 j=2 nxt[j-1]=0,j=0;
j=nxt[j-1]; //若是不相等的话 j返回到前缀的最后一个相等的nxt值 即123124 返回的是a[1] 的nxt值
}
}
}
int kmp()
{
int i=0;
int j=0;
while(i<n&&j<m) { //对子母 进行检索
if(s[i] == t[j]) {
i++;
j++;
} //若都相等的话都向后挪 ++
else if(!j) {
i++;
}
else {
j = nxt[j-1];
} //类同于求nxt
}
if(j == m)
return i-m+1; //若到最后能够遍历到j 则在母串中的位置为i-m+1
else
return -1; //否则返回-1
}