KMP算法
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e6+7;
int next[maxn];
string s,t;
void get_next(string str){
memset(next,0,sizeof(next));
for(size_t i=1,j=0;i<str.size();i++){
while(j>0&&str[i]!=str[j])
j=next[j-1];
if(str[j]==str[i])
j++;
next[i]=j;
}
}
void kmp(){
for(size_t i=0,j=0;i<s.size();i++){
while(j>0&&s[i]!=t[j])
j=next[j-1];
if(s[i]==t[j])
j++;
if(j==t.size())
printf("%d\n",i-j+1);
}
}
int main(){
ios::sync_with_stdio(false);
getline(cin,s);
getline(cin,t);
get_next(t);
kmp();
}
哈希
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const ull mag=1e4+7;
const int maxn=1e5+7;
ull magic[maxn],hs[maxn],ht[maxn];
void get_mag(int n){
magic[0]=1;
for(int i=1;i<=n;i++)
magic[i]=magic[i-1]*mag;
}
void get_hash(string s,ull h[]){
h[0]=s[0];
for(int i=1;i<s.size();i++)
h[i]=h[i-1]*mag+s[i];
}
ull get_int(int l,int r,ull h[]){
if(l==0) return h[r];
return h[r]-h[l-1]*magic[r-l+1];
}
int main(){
ios::sync_with_stdio(false);
string s,t;
cin>>s>>t;
int sz=s.size()-t.size();
get_mag(max(s.size(),t.size()));
get_hash(s,hs);
get_hash(t,ht);
for(int i=0;i<=sz;i++)
if(get_int(i,i+t.size()-1,hs)==ht[t.size()-1])
printf("%d\n",i);
}
AC自动机(有点复杂)
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int alp = 26;
const int maxn=5e5+7;
int head,tail;
char keyword[51];
char str[maxn*2];
struct node{
node *fail;
node *next[alp];
int count;
node(){
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
}*q[maxn];
void insert(char *str,node *root){
node*p=root;
for(int i=0,index;str[i];i++){
index=str[i]-'a';
node **tmp=&(p->next[index]);
if(*tmp==NULL)
*tmp=new node();
p=*tmp;
}
p->count++;
}
void bfail(node *root){
root->fail=NULL;
q[head++]=root;
while(head!=tail){
node *temp=q[tail++];
node *p=NULL;
for(int i=0;i<alp;i++)
if(temp->next[i]!=NULL){
if(temp==root)
temp->next[i]->fail=root;
else{
p=temp->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
temp->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
temp->next[i]->fail=root;
}
q[head++]=temp->next[i];
}
}
}
int query(node *root,char str[]){
int cnt=0;
node *p=root;
for(int i=0;str[i];i++){
index=str[i]-'a';
while(p->next[index]==NULL&&p!=root)
p=p->fail;
p=p->next[index];
p=(p==NULL)?root:p;
node *tmp=p;
while(tmp!=root&&tmp->count!=-1){
cnt+=temp->count;
tmp->count=-1;
tmp=tmp->fail;
}
}
return cnt;
}