【算法分析】
KMP算法把专注点放在了“已匹配的前缀”。KMP算法的核心,是一个next数组。
在KMP算法的众多实现中,有许多种定义next数组的方式。所以在使用和查看别人代码时,要特别注意KMP算法的next数组的定义,以免发生混淆。如:严蔚敏《数据结构》将模式串下标从1开始计数,故定义next[1]=0,next[2]=1。李春葆《数据结构》将模式串下标从0开始计数,故定义next[0]=-1,next[1]=0。但这两种定义方式,不影响它们有一致的计算方法,即“若第j-1位的字符与第x位的字符相等,则next[j]=x+1”(特别注意:在此确立相等的过程中,待比较的位x由已经计算出的next[j-1]~next[0]的值确定,而不是在模式串中从右向左依序确定)。此外,相应于不同的next数组定义方式,有“若直到第0位/第1位依然没有字符与第j-1位的字符相等,则next[j]=0/next[j]=1”。
例如,按李春葆《数据结构》中的定义方式(即定义next[0]=-1,next[1]=0),得出模式串abcabaa的next数组如下:
————————————————-
j 0 1 2 3 4 5 6
————————————————-
a b c a b a a
————————————————-
next[j] -1 0 0 0 1 2 1
————————————————-
【算法代码】
#include<bits/stdc++.h>
using namespace std;
const int maxn=100;
int next[maxn];
void getNext(string s) {
int len=s.length(); //First of all, you must calculate the length of the string.
int i=0, j=-1;
next[0]=-1;
while(i<len) {
if(j==-1 || s[i]==s[j]) {
next[++i]=++j;
} else j=next[j];
}
}
int main() {
string T;
getline(cin,T);
getNext(T);
for(int i=0;i<T.length();i++){
cout<<next[i]<<" ";
}
return 0;
}
/*
input: ababaaababaa
output: -1 0 0 1 2 3 1 1 2 3 4 5
*/