其实注意到next数组是到n+1的就差不多了,n+1次这就是表达了原串最多有几个前缀和后缀是相等的.
然后注意一下自己写的模板的字符串是从1开始的.然后对于next数组的理解嘛,他是要靠前面的next数组来辅助获得,所以在求next数组的时候有这个东西:k=next[k];对于k就是和书本的定义差不多.如果为0的时候就是属于第一种情况:
在利用next数组匹配的时候,如果j=0的话,那么i和j自增是因为第一个就不匹配的事情.
其他的就没什么了
My KMP Template:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <queue>
#include <cassert>
typedef long long ll;
#define clr(a) memset((a),0,sizeof (a))
#define rep(i,a,b) for(int i=(a);i<(int)(b);i++)
#define per(i,a,b) for(int i=((a)-1);i>=(int)(b);i--)
#define inf (0x7fffffff)
#define eps 1e-6
#define MAXN
#define MODN (1000000007)
using namespace std;
int next[1000];
char s[100],t[100];
void get_next(){
int len1=strlen(t+1);//求长度的时候是这么求的
int j=1;
int k=0;
next[1]=0;
while(j<=len1){
if(k==0 || t[j]==t[k]){//k跟书本的k的定义其实差不多
j++;
k++;
next[j]=k;
}
else{
k=next[k];
}
}
}
void kmp(){
int len1=strlen(s+1);
int len2=strlen(t+1);
int j=1;
int i=1;
for(;i<=len1&&j<=len2;){//如果是以逗号分开则是或的关系
if(s[i]==t[j]){
i++;
j++;
}
else{
j=next[j];
if(j==0){
i++;
j++;
}
}
}
if(j>len2) //j>=len2 && i<=len1,这个理由并不能验证成功,因为有可能是最后一个匹配成功.
//观察到j在匹配成功之后肯定是超过原串的长度的
{
cout<<" find it "<<endl;
cout<<i-len2<<endl; //注意这里返回的是位置,我的数组从1开始
}
else
cout<<"not find it "<<endl;
}
int main(){
while(cin>>s+1>>t+1){
get_next();
for(int i=1;i<=strlen(t+1);i++)
cout<<" "<<next[i];
cout<<endl;
kmp();
};
system("pause");
return 0;
}