KMP 字符串匹配
做 KMP 算法首先需要计算一个叫做前缀表的东西。


如上图所示,前缀表里面记录的是最长相等的前后缀长度。

当 b 发生不匹配时,由于前缀表对应的数字是 1,即将数组 P 向右拖到索引为 1 的位置,如上右图。
发现还是匹配不上,继续看前缀表,这时的位置是 0,于是再拖动数组 P,如下作图所示。当不匹配的时候,
前缀表出现 -1,意味着数组 T 的当前索引需要加 1,然后拖动 P 数组使 0 位置与 T 的当前位置对齐,如下右图。

怎么编写代码来获得这个前缀表呢?
void PrefixTable(char pattern[], int prefix[], int n)
{
int i = 1;
int len = 0;
prefix[0] = 0;
while (i < n) {
if (pattern[i] == pattern[len]) {
++len;
prefix[i] = len;
++i;
}
else {
if (len > 0) {
len = prefix[len - 1];
}
else {
prefix[i] = len;
++i;
}
}
}
}
void MovePrefixTable(int prefix[], int n)
{
for (int i = n - 1; i > 0; --i) {
prefix[i] = prefix[i - 1];
}
prefix[0] = -1;
}
void KmpSearch(char text[], char pattern[])
{
int i = 0, j = 0;
int n = strlen(pattern);
int m = strlen(text);
int* prefix = (int *)malloc(sizeof(int) * n);
PrefixTable(pattern, prefix, n);
MovePrefixTable(prefix, n);
while (i < m) {
if (j == n - 1 && text[i] == pattern[j]) {
printf("Found pattern!\n");
j = prefix[j];
}
if (text[i] == pattern[j]) {
++i;
++j;
}
else {
j = prefix[j];
if (j == -1) {
++i;
++j;
}
}
}
}
浙公网安备 33010602011771号