POJ 2752 Seek the Name, Seek the Fame (KMP next 数组 变形)

题意:给一个字符串S,判断在什么下标的时候,前缀和后缀相等,输出前缀和后缀相等的点。

分析:next数组的一种很巧妙的用法

next数组表示的意义是当前下标前面k字符和开头的前面k个字符相等

所以就会有xy=ab(用xy表示x - y的这一段),则next[b]=y,那么下次就从y这个位置开始匹配

如果xk=wy,因为xy=ab,故wy=lb,所以xk=lb,就得到了前缀和后缀相等。

详细见:http://www.mamicode.com/info-detail-977140.html
代码:

  #include<iostream>
  #include<cstdio>
  #include<cstdlib>
  #include<cstring>
  #include<queue>
  #include<algorithm>
  #include<cmath>
  #include<map>
  using namespace std;
  #define INF 0x7fffffff
  char s[400010];
  int next[400010];

  void get_next(){
      int i,j,len = strlen(s);
      next[0] = 0;
      next[1] = 0;
      for(i=1;i<len;i++){
	      j = next[i] ;
	      while(j && s[i] != s[j]) j = next[j] ;
	      if(s[i] == s[j]) next[i+1] = j+1 ;
	      else next[i+1] = 0 ;
      }
  }

  int main(){
      int i,j,num[400000],cnt;
      while(scanf("%s",s) == 1){
	      cnt = 0;
	      get_next();
	      int len =strlen(s);
	      j = len -1 ;
	      while(j){
		      i = j;
		      j = next[j];
		      while(j && s[i] != s[j]) j = next[j] ;
		      if(s[i] == s[j]) num[cnt++] = j+1 ;
		      else break ;
	      }
	      sort(num,num+cnt);
	      for(i=0;i<cnt;i++)
	          printf("%d ",num[i]);
	      printf("%d\n",len);
      }

      return 0;
  }
posted @ 2015-08-31 22:27  阿文的博客  阅读(161)  评论(0编辑  收藏  举报