KMP 算法模板

/*kmp 模板 2014年10月18日*/
#include<iostream>
using namespace std;
int f[100];
void getFail(char* p, int* f)//预处理子串
{
int m = strlen(p);
f[0] = 0;
f[1] = 0;
for (int i = 1; i < m; i++)
{
int j = f[i];
while (j && p[i] != p[j])
{
j = f[j];//进行回溯
}
f[i + 1] = p[i] == p[j] ? j + 1 : 0;//记录未匹配的下标 处理到 i+1位
}
}
int find(char* t, char*p, int*f)//匹配
{
int n = strlen(t), m = strlen(p);
getFail(p, f);
int j = 0;
for (int i = 0; i < n; i++)
{
while (j && p[j] != t[i])
{
j = f[j];//回溯
}
if (p[j] == t[i])
{
j++;
}
if (j == m)
{
return i - m + 1;//返回当前位置
}
}
return -1;
}
int main()
{
char *p = "abcabcdda";
char *t = "babdabcabcabcddaaaa";
if(find(t,p, f)==-1)
{
cout << "No" << endl;
}
else cout << "Yes"<<"位置为"<<find(t,p,f) << endl;
return 0;
}

其实kmp的思想还是很好理解的,就是代码不太好实现,看别人的模板才写出来。。
这里假设  p是t 的子串,p串的长度为n,子串t的长度m;
kmp的目:求出子串t在p串中的位置。
kmp的思想:先预处理子串t,处理出如果子串t中第1个到第m个字符 失配时应该回溯的位置(这里的位置指数组的下标)并保存到数组f[]中
KMP 算法模板_第1张图片
如模板的做法,预处理的时候主要是递推。而且这段预处理的代码和实际匹配的代码很像。
kmp的实际匹配:从下标0开始扫t串,如果p[j]!=t[i] 进行回溯找到j的回溯位置
KMP 算法模板_第2张图片
 

你可能感兴趣的:(KMP 算法模板)