KMP算法源码
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define _CRT_SECURE_NO_DEPRECA TE
#include
#include
#include
#include
using namespace std;
#define N 100
void cal_next(char * str, int * next, int len)
{
int i, j;
next[0] = 0;
for (i = 1; i < len; i++)
{
j = next[i - 1];
while (str[j] != str[i] && (j > 0))//直到对称子串中再无最长前后缀
{
j = next[j-1]; //或者在对称子串中找到一个之前满足条件的最长前缀
}
if (str[i] == str[j])
{
next[i] = j + 1;
}
else
{
next[i] = 0;
}
}
}
int KMP(char * str, int slen, char * ptr, int plen, int * next)
{
int s_i = 0, p_i = 0;
int i;
printf("%s\n",str);
printf("%s\n",ptr);
while (s_i < slen && p_i < plen)
{
if (str[s_i] == ptr[p_i])
{
s_i++;
p_i++;
continue;
}
else
{
if (p_i == 0)
{
s_i++;
}
else
{
p_i = next[p_i-1]; //取当前匹配不到之前的字符串的最大相等前缀的最后一个字符
}
}
for (i = 0; i < s_i - p_i; i++)
{
putchar(' ');
}
printf("%s\n",ptr);
}
return (p_i == plen) ? (s_i - plen) : -1;//返回第一次找到子串的下标位置
}
int main()
{
char str[N] = { 0 };
char ptr[N] = { 0 };
int slen, plen;
int next[N];
int ret;
printf("请输入主串:");
scanf("%s",str);
printf("请输入模式串:");
scanf("%s",ptr);
slen = strlen(str);
plen = strlen(ptr);
cal_next(ptr, next, plen);
printf("\nnext:");
for (int i = 0; i < strlen(ptr); i++)
printf("%2d", next[i]);
printf("\n");
ret = KMP(str, slen, ptr, plen, next);
if (ret == -1)
printf("主串中未找到模式串\n");
else
printf("第一次找到的位置位于主串的下标是: %d\n", ret);
system("pause");
return 0;
}