kmp:通过next数组来对字符串匹配进行简化
char s[maxn],l[maxm];
int next[maxm];
- next数组:
next[i]表示1-i中前缀等于后缀的最大长度
如:
data: a b c a b c
next: 0 0 0 1 2 3
inline void get_next(){
next[1]=0;
int j=0,ll=strlen(l+1);
for(int i=2;i<=ll;i++){
while(j>0&&l[j+1]!=l[i])j=next[j];
if(l[j+1]==l[i]) ++j;
next[i]=j;
}
}
- 求解过程
inline bool kmp(){
int j=0,ll=strlen(l+1),sl=strlen(s+1);
for(int i=1;i<=sl;i++){
while(j>0&&s[i]!=l[j+1]) j=next[j];
if(s[i]==l[j+1]) ++j;
if(j==ll){
cout<<i-j+1<<endl;
j=next[j];
m=true;
}
}
}
- 下面贴出完整代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
//-------------------
char s[1000000+50],l[1000000+50];
int next[1000000+50];
bool m;
//-------------------
inline void get_next(){
next[1]=0;
int j=0,ll=strlen(l+1);
for(int i=2;i<=ll;i++){
while(j>0&&l[j+1]!=l[i])j=next[j];
if(l[j+1]==l[i]) ++j;
next[i]=j;
}
}
inline bool kmp(){
int j=0,ll=strlen(l+1),sl=strlen(s+1);
for(int i=1;i<=sl;i++){
while(j>0&&s[i]!=l[j+1]) j=next[j];
if(s[i]==l[j+1]) ++j;
if(j==ll){
cout<<i-j+1<<endl;
j=next[j];
m=true;
}
}
}
//--------------------
int main(){
freopen("h.in","r",stdin);
cin>>s+1>>l+1;
// cout<<s+1<<endl<<l+1<<endl;
get_next();
kmp();
if(!m) cout<<"NO";
return 0;
}