经过几天的学习,终于理解了 KMP算法的基本原理。
下面是据此实现的函数。
1.生成 next array 的函数
#include <string.h>
void GetNext(char *pattern, int *next )
{
int i = 1;
int j = 0;
int patternSize = strlen(pattern);
next[0] = 0;
while( i < patternSize)
{
if(pattern[j] == pattern[i])
{
next[i] = j + 1;
++i;
++j;
}
else if(j > 0)
{
j = next[j - 1];
}
else
{
next[i] = 0;
i++;
}
}
}
2. KMP 匹配函数:
#include <string.h>
#include <stdlib.h>
extern void GetNext(char *pattern, int *next);
int KMPMatch(char *text, char *pattern)
{
int patternSize = strlen(pattern);
int textSize = strlen(text);
int *nextArray = (int *)malloc(patternSize * sizeof(int));
GetNext(pattern, nextArray);
int i = 0, j = 0;
while(i < textSize)
{
if(pattern[j] == text[i])
{
if(j == patternSize - 1)
{
free(nextArray);
return i - patternSize + 1;
}
++i;
++j;
}
else if(j > 0)
{
j = nextArray[j - 1];
}
else
{
++i;
}
}
free(nextArray);
return -1;
}
3. 测试函数:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern void GetNext(char *pattern, int *next);
extern int KMPMatch(char *text, char *pattern);
int main(void)
{
char *pattern = "abaabacab";
char *text = "cabaaababaabacab";
int *next = (int *)malloc(strlen(pattern) * sizeof(int));
memset(next, 0, strlen(pattern));
int index = KMPMatch(text, pattern);
GetNext(pattern, next);
int i;
for(i = 0; i < strlen(pattern); i++)
{
printf("%c ", pattern[i]);
}
printf("\n");
for(i = 0; i < strlen(pattern); ++i)
{
printf("%d ", next[i]);
}
printf("\n");
printf("index = %d\n", index);
return 0;
}
运算结果:
$ ./a.out
a b a a b a c a b
0 0 1 1 2 3 0 1 2
index = 7