#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
void prefix_table(int prefix[], char pattern[], int n)
{
int len = 0;
int j = 1;
prefix[0] = 0;
while (j < n)
{
if (pattern[j] == pattern[len])
{
++len;
prefix[j] = len;
++j;
}
else
{
if (len > 0)
len = prefix[len - 1];
else
{
prefix[j] = len;
++j;
}
}
}
}
void move_prefix_table(int n, int prefix[])
{
for (int i = n - 1; i >= 1; --i)
prefix[i] = prefix[i - 1];
prefix[0] = -1;
}
void kmp_search(char pattern[], char text[])
{
int n = strlen(pattern);
int m = strlen(text);
int *prefix = (int*)malloc(n * sizeof(int));
prefix_table(prefix, pattern, n);
move_prefix_table(n, prefix);
int i = 0, j = 0;
while (i < m)
{
if (j == n - 1 && text[i] == pattern[j])
{
cout << "find it at" << i - j << endl;
j = prefix[j];
}
if (pattern[j] == text[i])
{
++i;
++j;
}
else {
j = prefix[j];
if (j == -1) {
++j;
++i;
}
}
}
free(prefix);
}
int main()
{
char pattern[] = "ABCABCAAB";
char text[] = "AAAABABCABCAABA";
kmp_search(pattern, text);
return 0;
}