Period II - FZU 1901(KMP->next)
题目大意:给你一个字符串 S ,N = |S|,如果存在一个 P (1<=P<=N),并且满足 s[i] = s[P+i] (i = {0...N-P-1} ),求出来所有的 P 然后输出.
分析:其实就是这个字符串的后缀与前缀的最大匹配 next[N],然后用最大匹配的串继续找匹配的前缀,比如下面的数据:
aaabaaa:--> P = 4 <---> next[7] = 3
aaabaaa:--> P = 5 <---> next[3] = 2
aaabaaa:--> P = 6 <---> next[2] = 1
aaabaaa:--> P = 7 <---> next[1] = 0
比较明显的可以看出来怎么求这些数了吧.....
代码如下:
=========================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<stdlib.h> using namespace std; const int MAXN = 1e6+7; char s[MAXN]; int Next[MAXN], ans[MAXN]; void GetNext(char s[], int len) { int i=0, j=-1; Next[0] = -1; while(i<len && j<len) { if(j==-1 || s[i]==s[j]) Next[++i] = ++j; else j = Next[j]; } } int main() { int T, t=1; scanf("%d", &T); while(T--) { scanf("%s", s); int len = strlen(s); GetNext(s, len); int cnt = 0, k=len; while(Next[k] != 0) { ans[cnt++] = len-Next[k]; k = Next[k]; } printf("Case #%d: %d\n", t++, cnt+1); for(int i=0; i<cnt; i++) printf("%d ", ans[i]); printf("%d\n", len); } return 0; } /** 2 aaabaaa Case #1: 4 4 5 6 7 **/