pku2406 Power Strings(kmp字符匹配,next数组)

   重看了下数据结构,发现有些知识还没有吃透。kmp算法就是一个。kmp的关键就是next数组,求出了next数组后就和O(n*m)的算法类似。求next数组有dp的思想,假设知道next[i]=k,现在要求next[i+1],
                next[i]+1   ch[i]=ch[i+1]
   next[i+1]=   next[k']+1  沿着前面的next数组找到一个k',ch[k']=ch[i+1],简单情况就是k'=next[i]
                0           其他情况
书上还说的了next数组的优化,当ch[k]==ch[i+1]时,next[i+1]=next[k]。
附段伪代码:
algorithm kmp_search:
input:
an array of characters, S (the text to be searched)
an array of characters, W (the word sought)
output:
an integer (the zero-based position in S at which W is found)

define variables:
an integer, m ← 0 (the beginning of the current match in S)
an integer, i ← 0 (the position of the current character in W)
an array of integers, T (the table, computed elsewhere)

while m + i is less than the length of S, do:
if W[i] = S[m + i],
let i ← i + 1
if i equals the length of W,
return m
otherwise,
let m ← m + i - T[i],
if i is greater than 0,
let i ← T[i]

(if we reach here, we have searched all of S unsuccessfully)
return the length of S
  1. #include <iostream>
  2. using namespace std;
  3. #include <string.h>
  4. #define pr printf
  5.  char ch[1003003];
  6. int next[1003003];
  7. int main(int argc, char** argv) {
  8.     int len,i;
  9.     while(scanf("%s",ch))
  10.     {
  11.         len=strlen(ch);///书上的算法,数据结构
  12.         if(len==1 && ch[0]=='.')break;
  13.         next[1]=0;int j=0;i=1;
  14.         while(i<len)
  15.         {
  16.             if(j==0 ||ch[i]==ch[j]){++i,++j;next[i]=j;}
  17.             else j=next[j];
  18.         }
  19.         int tmp,cur,l; 
  20.             l=len-next[len];
  21.             tmp=len/(len-next[len]);
  22.         if(len%l!=0){pr("1/n");continue;}
  23.             else {
  24.                  cur=l-1;
  25.                  for(cur;cur<len;cur+=l)if(ch[cur]!=ch[l-1])break;
  26.                 if(cur>=len){
  27.                     pr("%d/n",tmp);
  28.                 }else pr("1/n");
  29.             }
  30.     }
  31.     return (EXIT_SUCCESS);
  32. }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值