自己的机子上用DEVC尽然出现异常在别人机子上没事,郁闷死,弄了超久才弄出来,汗,有空一会出个解题报告
- #include<iostream>
- #include<string>
- #include<malloc.h>
- #include<stdlib.h>
- using namespace std;
- int *nextval;
- void get_nextval(string s,int *next)
- {
- next[0]=-1;
- int j=0,i=-1,s_len=s.size();
- while(j<s_len)
- {
- if(i==-1||s[j]==s[i]) {
- i++;
- j++;
- if(s[j]!=s[i])
- next[j]=i;
- else
- next[j]=next[i];
- }
- else
- i=next[i]; }
- }
- int Index_KMP(string s,string t,int pos)
- {
- int i=pos-1,j=0,s_len=s.size(),t_len=t.size();
- while(i<s_len&&j<t_len)
- {if(j==-1||s[i]==t[j]) {++i;++j;}
- else j=nextval[j];
- }
- if(j==t_len) return i-t_len+1;
- else return 0;}
- int main()
- {
- string s,t;
- while(cin>>s>>t)
- {
- nextval=(int*)malloc(t.size()*sizeof(int));
- get_nextval(t,nextval);
- for(size_t i=0;i<t.size();i++)
- cout<<nextval[i]<<" ";
- cout<<endl;
- cout<<Index_KMP(s,t,1)<<endl;
- free(nextval);
- }
- return 0;
- }
- }
解题报告(自己归纳的):
求next数组的算法自己整理了下
p 1p2......p(j-1)=s(i-j+1)....s(i-1)
p1p2...pk-1=s(i-k+1)...s(i-1)=p(j-k+1)....p(j-1)
就是求当pj!=si的时候,求k的最大值(1<k<j)
对于任意的j都有一个对应的k值,用int next[n+1]数组表示,(next[0]不使用)
next[1]=0
设next[j]=k;即 'p1....p(k-1)'='p(j-k+1)....p(j-1)'
当pk=pj时,即 'p1....p(k-1)pk'='p(j-k+1)....p(j-1)pj'
所以next[j+1]=k+1=next[j]+1;
当pk!=pj时 就要使j=k=next[j],让si与pk比较,如果相等则进行s(i+1)和p(k+1)比较
如果不等,则令j=k'=next[k],让si与pk'比较,以此类推,直到j=0的时候,即整个模式串中都没有与si之前匹配的串,这时候就要令i+1,j+1,进行s(i+1)和p(k+1)比较
next改进为nextval的算法
si!=pj
当pk=pj时,继续进行p(k+1)与p(j+1)的比较,
如果相等的情况下,即si!=pj所以si!=pk,如果pk==pk',以此类推,直到j回溯到
j=k(n)!=k(n-1)=··k''=k'
此算法就是为了省略模式串中这种情况下j指针的回溯,
所以当pk=pj时,继续进行p(k+1)与p(j+1)的比较,
如果不等则同next算法,
如果相等则把串某一段都是相同元素子串的第一个元素的nextval[]的值赋值给该子串的所有元素