加油准备5.11 的比赛了!
之前就看过一遍这个链接,但是这次看发现之前是白看的,有点误解。
kmp算法的next数组是是核心,
k= next [ j ]数值的含有是匹配串的的第j个字符的前k个字符和匹配串的0~k个字相同
这句话有点绕,可以看下图
可以理解成将当第j个字符和主串不相匹配后,将j=next[ j ]因为在匹配过程中
匹配串的0~j-1 都匹配了,然后再匹配串自身中 有 0~next[ j ]== j - next [ j] ~ j-1 其实就是上面那张图,
所以直接可以将 j = next [ j ].
所以next数组是只要匹配串就能得出 ,和主串没关系 !!
kmp算法模板
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std ;
const int MAX = 1005 ;
typedef long long LL ;
int next[MAX] ; // next数组
void getNextVal(char *p){
int plen = strlen(p) ;
next[0] = -1 ;
int k = -1 ;
int j = 0 ;
while(j<plen){
if(k == -1 || p[j]==p[k]){
j++ ;
k++ ;
if(p[j]!=p[k]){
next[j] = k ;
}
else{
next[j] = next[k] ;
}
}
else{
k = next[k] ;
}
}
}
int kmp(char *s , char *p) {
// s 是模式串, p 是匹配串
int i = 0 , j = 0 ;
getNextVal(p) ;
int slen = strlen(s) ;
int plen = strlen(p) ;
while(i<slen && j <plen ){
if(j == -1 || s[i]==p[j]){
i++ ;
j++ ;
}
else{
j = next[j] ;
}
}
if(j == plen ){
return i-j ;
}
else{
return -1 ;
}
}
int main(){
char s[1005] , p[1005] ;
cin >>s >> p ;
int pos = kmp(s,p) ;
cout<<pos <<endl ;
return 0 ;
}