来源:POJ2752
KMP的一个运用,关键是要理解next指针
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
string str;
const int MAXN = 400000+10;
int nxt[MAXN];
int len;
void get_next(){
int i,j;
memset(nxt,0,sizeof(nxt));
i = 0;
nxt[0] = -1;
j=-1;
// cout<<"len: "<<len<<endl;
while(i<len){
// cout<<"j: "<<j<<endl;
if(j==-1 || str[i]==str[j]){
i++;
j++;
nxt[i] = j;
}
else{
j = nxt[j];
}
}
}
int ans[MAXN];
int main(){
//理解next数组的意义的话,其实这个就是从最后不断向前跳转的next序列
//next[j]数组的理解是:s[0~t]和s[j-t~j]匹配的最大的t
//那么这样的前缀我已经有了,所以只要保证s[j-t~j]是后缀就行
//那么这个题目就结束了
while(cin>>str){
len = str.length();
// cout<<str<<endl;
get_next();
int k=nxt[len-1];
int cnt=0;
while(k!=-1){
if(str[k]==str[len-1]){
//cout<<"yes"<<endl;
ans[cnt++] = 1+k;
}
k = nxt[k];
//cout<<k<<endl;
}
for(int i=cnt-1;i>=0;i--){
cout<<ans[i]<<" ";
}
cout<<len<<endl;//串本身必然成立
}
return 0;
}