kmp模板题,也可用哈希
kmp版
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<cctype>
#include<queue>
using namespace std;
const int N=1e6+5;
char s[N],t[N];
int sn,tn,bz=1,next[N];
void getnext()
{
for(int i=1,j=0;i<tn;i++)
{
while(j&&t[i]!=t[j])j=next[j-1];
if(t[i]==t[j])j++;
next[i]=j;
}
}
void kmp()
{
for(int i=0,j=0;i<sn;i++)
{
while(j&&s[i]!=t[j])j=next[j-1];
if(s[i]==t[j])j++;
if(j==tn)
{
bz=0;
cout<<i-tn+2<<'\n';
}
}
}
int main()
{
//freopen("lx.in","r",stdin);
scanf("%s%s",s,t);
sn=strlen(s),tn=strlen(t);
getnext();
kmp();
if(bz)cout<<"NO";
return 0;
}
哈希版(unsigned long long会自然溢出,相当于mod一个数,所以基数可用适当大的素数避免冲突)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=1e6+5,base=61;
char s[N],t[N];
int sn,tn;
unsigned long long num,bin[N],hash[N];
int main()
{
//freopen("lx.in","r",stdin);
scanf("%s%s",s+1,t+1);
sn=strlen(s+1),tn=strlen(t+1);
for(int i=tn;i>=1;i--)num=num*base+t[i]-'a';
for(int i=sn;i>=1;i--)hash[i]=hash[i+1]*base+s[i]-'a';
bin[0]=1;
for(int i=1;i<=tn;i++)bin[i]=bin[i-1]*base;
int bz=1;
for(int i=1;i<=sn-tn+1;i++)
{
if(hash[i]-hash[i+tn]*bin[tn]==num)
{
bz=0;
cout<<i<<endl;
}
}
if(bz)cout<<"NO";
return 0;
}