/*
* KMP
*/
#include <iostream>
#include <cstring>
using namespace std;
/*
* next
* , ,
* O(m),m
*/
void countNext(char* strPattern, int len, int* next)
{
int i = 0, j = -1;
next[i] = j;
while (i < len-1)
{
if (j == -1)
{
i++;
j++;
next[i] = j;
} else if (strPattern[i] == strPattern[j]) {
i++;
j++;
if (strPattern[i] != strPattern[j])
{
next[i] = j;
} else {
next[i] = next[j];
}
} else {
j = next[j];
}
}
}
/*
* KMP
* KMP O(n)+O(m) = O(n+m)
* n ,m , next
* KMP ,
* , , ,
* , , KMP
*/
int indexKMP(char* strMain, int lenMain, char* strPattern, int lenPattern, int pos, int* next)
{
int i = pos, j = 0;
while (i < lenMain && j < lenPattern)
{
if (j == -1 || strMain[i] == strPattern[j])
{
i++;
j++;
} else {
j = next[j];
}
}
if (j >= lenPattern)
{
return i - lenPattern;
}
return -1;
}
int main()
{
char* strPattern = "abce";
char* strMain = "ksekabcedwfabcekf";
int lenMain = strlen(strMain);
int lenPattern = strlen(strPattern);
int* next = new int[lenPattern];
countNext(strPattern, lenPattern, next);
int startPos = 5;
int pos = indexKMP(strMain, lenMain, strPattern, lenPattern, startPos, next);
if (pos < 0)
{
cout<<" "<<strMain<<" "<<startPos+1<<" "<<strPattern<<endl;
} else {
cout<<" "<<strMain<<" "<<startPos+1<<" "<<strPattern<<" "<<pos+1
<<" "<<endl;
}
delete[] next;
return 0;
}