KMP算法源码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;

}

相关文档
最新文档