KMP 算法 与 朴素算法相比少了不必要的重复工作,比如ABABCD串在C处失配应从第二个A处匹配,不是第一个A处匹配。所以KMP的关键是状态转移表(预处理时间是0(M)),总的时间复杂度是0(M + N)。
状态转移就是模式串每个位置的最大相等子串。
前提:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; char w[10010]; char t[1000010]; int next[10010]; int cnt;
void get_next()
{
next[0] = 0;
next[1] = 0;
int j ;
for(int i = 1; w[i]!= ‘\0‘; i ++)
{
j = next[i];
while(j && w[j] != w[i]) j = next[j];
next[i+1] = w[j] == w[i] ? j + 1: 0;
}
}则next[i+1] = L+1(0 ,1,2,3,....,L),如果w[i] != w[j](w[i] != w[L]),最大相等子 串为0,next[i+1] = 0;
匹配过程:
void kmp()
{
int j = 0 , m = strlen(w);
for(int i = 0; t[i] != ‘\0‘; i ++)
{
while(j && w[j] != t[i]) j = next[j];
if(w[j] == t[i]) j ++;
if(j == m) cnt ++;
}
}#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char w[10010];
char t[1000010];
int next[10010];
int cnt;
void get_next()
{
next[0] = 0;
next[1] = 0;
int j ;
for(int i = 1; w[i]!= ‘\0‘; i ++)
{
j = next[i];
while(j && w[j] != w[i]) j = next[j];
next[i+1] = w[j] == w[i] ? j + 1: 0;
}
}
void kmp()
{
int j = 0 , m = strlen(w);
for(int i = 0; t[i] != ‘\0‘; i ++)
{
while(j && w[j] != t[i]) j = next[j];
if(w[j] == t[i]) j ++;
if(j == m) cnt ++;
}
}
int main()
{
int n ;
scanf("%d",&n);
while(n --)
{
scanf("%s",w);
nex();
cnt = 0;
scanf("%s",t);
kmp();
cout << cnt << endl;
}
return 0;
}
原文:http://blog.csdn.net/wuhuajunbao/article/details/22900491