若原串中首字符与后续字符依次相同,则可以用next[1]取代后续的next[j]
改良后的KMP算法,在计算出next值的同时,如果a位字符与它next值指向的b位字符相等,则该a位的nextval就指向b位的nextval值,如果不等,则该a位的nextval值就是它自己a位的next值。
//KMP改良版
#include <iostream>
using namespace std;
const int MAXSIZE = 255;
typedef struct{
char ch[MAXSIZE+1];
int length;
}SString;
void get_nextval(SString T, int *next);
int Index_KMP(SString S, SString T, int pos);
void put_String(SString &T);
int main()
{
SString a, b;
put_String(a);
put_String(b);
cout << Index_KMP(a, b, 1);
return 0;
}
void get_nextval(SString T, int *nextval)
{
int i = 1, j = 0;
nextval[1] = 0;
while (i < T.length)
{
if (j == 0 || T.ch[i] == T.ch[j])
{
i++;
j++;
if (T.ch[i] != T.ch[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else
j = nextval[j];
}
}
int Index_KMP(SString S, SString T, int pos)
{
int i = pos, j = 1;
int next[255];
get_nextval(T, next);
while (i <= S.length && j <= T.length)
{
if (j == 0 || S.ch[i] == T.ch[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j > T.length)
return i - T.length;
return 0;
}
void put_String(SString &T)
{
int i;
cin >> T.length; //输入字符串长度
for (i = 1; i <= T.length; i++)
cin >> T.ch[i];
}