#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int GenNext(char *mod, int len, int next[])
{
if (mod == NULL || next == NULL || len <= 0)
return -1;
next[0] = -1;
int k = -1;
int j = 0;
while (j < len - 1)
{
if (k == -1 || mod[k] == mod[j])
{
k++;
j++;
next[j] = next[k] + 1;
}
else
{
k = next[k];
}
}
return 1;
}
int KmpSearch(char *text, char *mod)
{
if (text == NULL || mod == NULL)
return -1;
int modlen = strlen(mod);
int *next = (int *)malloc(sizeof(int) * modlen);
if (!next)
{
return -1;
}
if (GenNext(mod, modlen, next) < 0)
return -1;
int i = 0, j = 0;
int textlen = strlen(text);
while (i < textlen && j < modlen && j != -1)
{
if (text[i] == mod[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
free(next);
if (j == modlen)
return i - j;
else
return -1;
}
int main(int argc, char *argv[])
{
char text[256], mod[16];
printf("Please input text:");
scanf("%s", text);
printf("Please input mod:");
scanf("%s", mod);
int index = KmpSearch(text, mod);
printf("Index[%d] OK\n", index);
return 0;
}
主要思路是先用一个next数组保存模式字符串的最长前缀后缀字符串,在匹配时就可以根据next数组快速匹配,时间复杂度O(n+m), 空间复杂度O(m).