#include<iostream>
#include<cstring>
using namespace std;
int* make_pmt(const char *p) //得到回溯的数组
{
unsigned int len = strlen(p);
int *ret = static_cast<int *>(malloc(sizeof(int)*len));
if (NULL != ret)
{
ret[0] = 0;
int ll = 0;
for (unsigned int i = 1; i < len; i++)
{
while (ll > 0 && p[ll] != p[i])
{
ll = ret[ll - 1];
}
if (p[ll] == p[i])
{
ll++;
}
ret[i] = ll;
}
}
return ret;
}
int KMP(const char *s, const char *p)
{
int ret = -1;
int sl = strlen(s);
int pl = strlen(p);
int *pmt = make_pmt(p);
for (int i = 0, j = 0; i < sl; i++)
{
while ((j > 0) && (s[i] != p[j]))
{
j = pmt[j - 1];
}
if (s[i] == p[j])
{
j++;
}
if (j == pl)
{
ret = i + 1 - pl;
break;
}
}
free(pmt);
return ret;
}
int main()
{
//测试数据1,如果匹配到了就返回相应的下标,没有匹配到就返回-1
int n = KMP("abcde","cde");
cout << n << endl;
//测试数据2
n = KMP("abcde", "bcde");
cout << n << endl;
return 0;
}