KMP 算法详解
KMP模式搜索算法动画演示
KMP是一种高效的字符串匹配算法,用来在主字符串中查找模式字符串的位置(如:在字符串“Hello,world!”中查找“world”模式串的位置)
粗略看了上面的KMP详解和动画演示,应该都对其中出现的next数组有较深刻的印象,而next数组也是KMP算法省时的关键。
next[]数组的性质:
next [ i ] 表示模式串P中以 i(下表从 i 开始)结尾的后缀(能匹配的P的前缀的最大长度)。
next [ i ] = j,表示 P [ i - j + 1,i ]
以 i=0 开始的预处理 next 的模板:
memset(next,0,sizeof (next));
for (int i=1,j=0;i<n;i++) {
while (j&&p[i]!=p[j]) j=next[i]; //i,j指的值不等时,不断寻找之前的值
if (p[i]==p[j]) j++; //当i,j指的值相等时,j+1,准备进行下一值的比较
next[i+1]=j;
}
以 i=0 开始的KMP模板:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int M=1e6+5;
int next[M];
char p[M],a[M];
int main() {
int t; cin>>t;
while (t--) {
int sum=0;
scanf("%s%s",&p,&a); //p--要找的串 a--大串
//p预处理
int lenp=strlen(p),lena=strlen(a);
for (int i=1,j=0;i<lenp;i++) {
while (j&&p[i]!=p[j]) j=next[j];
if (p[i]==p[j]) j++;
next[i+1]=j;
}
for (int i=0,j=0;i<lena;i++) {
while (j&&p[j]!=a[i]) j=next[j];
if (p[j]==a[i]) j++;
if (j==lenp) {
j=next[j];
sum++;
}
}
printf("%d\n",sum);
memset(a,0,sizeof a);
memset(p,0,sizeof p);
memset(next,0,sizeof next);
}
return 0;
}