//参考算法导论
#include <string.h>
#include <stdio.h>// 前缀函数
int *compute_prefix_function(const char *needle)
{
int len = strlen(needle);
int *c = new int[len];
memset(c, 0, len * sizeof(int));
c[0] = 0;
int k = 0;
for(int q = 2; q <= len; ++q)
{
while(k > 0 && needle[k] != needle[q - 1]) {
k = c[k - 1];
}
if(needle[k] == needle[q - 1]) {
++k;
}
c[q - 1] = k;
}
printf("the value of prefix function array:\n");
for (int i = 0; i < len; ++i) {
printf("%6d", c[i]);
}
printf("\n");
return c;
}
void kmp_matcher(const char *haystack, const char *needle)
{
int n = strlen(haystack);
int m = strlen(needle);
int *c = new int[m];
memset(c, 0, m * sizeof(int));
c = compute_prefix_function(needle);
int q = 0;
for(int i = 1; i <= n; i++)
{
while(q > 0 && needle[q] != haystack[i - 1]) {
q = c[q - 1];
}
if(needle[q] == haystack[i - 1]) {
q = q + 1;
}
if(q == m)
{
printf("Pattern occurs with shift %d \n",i-m+1);
q = c[q - 1];
}
}
}
int main()
{
const char * haystack = "bacbababaabcbab";
const char * needle = "ababa";
printf("haystack = %s\n needle = %s\n", haystack, needle);
kmp_matcher(haystack, needle);
return 0;
}