- 当j增加1时,j的match值有两种情况
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int Position;
#define NotFound -1
void BuildMatch(char *pattern, int *match)
{ // 为pattern建立相应的match值
Position i, j;
int m = strlen(pattern);
match[0] = -1;
for (j=1; j<m; j++) {
i = match[j-1];
while ((i>=0) && (pattern[i+1]!=pattern[j]))
i = match[i]; // i回退
if (pattern[i+1] == pattern[j]) {
match[j] = i+1;
} else
match[j] = -1;
}
}
Position KMP(char *string, char *pattern)
{
int n = strlen(string);
int m = strlen(pattern);
Position s, p, *match;
if (n < m) return NotFound;
match = (Position *)malloc(sizeof(Position) * m);
BuildMatch(pattern, match); // 为pattern建立相应的match值
s = p = 0;
while (s<n && p<m) {
if (string[s] == pattern[p]) {
s++; p++;
}
else if (p>0) p = match[p-1]+1; // s与p匹配失败时,p回退到p-1的match值+1处
else s++; // 如果p=0时,说明pattern首字符就不能与s所指字符匹配,因此,s+1,指向下一个字符,重新匹配
}
// s指针一直往前走,没有回退,因此如果匹配成功,返回的下标应该是s-m
return (p == m)? (s - m): NotFound;
}
int main()
{
char string[] = "This is a simple example.";
char pattern[] = "simple";
Position p = KMP(string, pattern);
if (p == NotFound) printf("Not Found.\n");
else printf("%s\n", string+p);
return 0;
}