重看了下数据结构,发现有些知识还没有吃透。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]。
附段伪代码:
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
- #include <iostream>
- using namespace std;
- #include <string.h>
- #define pr printf
- char ch[1003003];
- int next[1003003];
- int main(int argc, char** argv) {
- int len,i;
- while(scanf("%s",ch))
- {
- len=strlen(ch);///书上的算法,数据结构
- if(len==1 && ch[0]=='.')break;
- next[1]=0;int j=0;i=1;
- while(i<len)
- {
- if(j==0 ||ch[i]==ch[j]){++i,++j;next[i]=j;}
- else j=next[j];
- }
- int tmp,cur,l;
- l=len-next[len];
- tmp=len/(len-next[len]);
- if(len%l!=0){pr("1/n");continue;}
- else {
- cur=l-1;
- for(cur;cur<len;cur+=l)if(ch[cur]!=ch[l-1])break;
- if(cur>=len){
- pr("%d/n",tmp);
- }else pr("1/n");
- }
- }
- return (EXIT_SUCCESS);
- }