字符串模板汇总
字符串模板
KMP
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=1000010;
int n,m,next[MAXN];
char a[MAXN],b[MAXN]; //a为主串,b为模式串
int main(){
scanf("%s%s",a+1,b+1);
n=strlen(a+1),m=strlen(b+1);
int j=0;
next[1]=0;
for(int i=1;i<m;++i){
while(j&&b[j+1]!=b[i+1]) j=next[j];
if(b[j+1]==b[i+1]) ++j;
next[i+1]=j;
}
j=0;
for(int i=0;i<n;++i){
while(j&&b[j+1]!=a[i+1]) j=next[j];
if(b[j+1]==a[i+1]) ++j;
if(j==m){
printf("%d\n",i-j+2); //字符串a的第(i+1)-j+1个字母开头的字符与b匹配
j=next[j];
}
}
for(int i=1;i<=m;++i)
printf("%d ",next[i]);
puts("");
return 0;
}
manacher
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=22000010;
int n,p[MAXN];
char s[MAXN],a[MAXN];
int main(){
scanf("%s",s+1);
n=strlen(s+1);
a[0]='$';
for(int i=1;i<=n;++i)
a[i*2-1]='$',a[i*2]=s[i];
a[n*2+1]='$';
n=n*2+1;
int k=0,mx=0;
for(int i=1;i<=n;++i){
if(i<=mx) p[i]=min(mx-i,p[k*2-i]);
while(a[i+p[i]+1]==a[i-p[i]-1]) ++p[i];
if(i+p[i]>mx) mx=i+p[i],k=i;
}
int Ans=0;
for(int i=1;i<=n;++i)
Ans=max(Ans,p[i]);
printf("%d\n",Ans);
return 0;
}
哈希字符串匹配
#include<iostream>
#include<cstring>
#include<cstdio>
#define LL long long
using namespace std;
const int MAXN=1000010;
const int MOD=1e9+7;
const int Base=27;
int n,m,nxt[MAXN];
char s1[MAXN]; //主串
char s2[MAXN]; //模式串
LL Hash[MAXN],p[MAXN],hashs2;
LL get_Hash1(int l,int r){
return (Hash[r]-Hash[l-1]*p[r-l+1]%MOD+MOD)%MOD;
}
int main(){
scanf("%s",s1);
scanf("%s",s2);
n=strlen(s1);
m=strlen(s2);
p[0]=1;
for(int i=0;i<n;++i){
Hash[i]=(Hash[i-1]*Base+s1[i]-'A'+1)%MOD;
p[i+1]=p[i]*Base%MOD;
}
for(int i=0;i<m;++i)
hashs2=(hashs2*Base+s2[i]-'A'+1)%MOD;
for(int i=0;i+m-1<n;++i){
if(get_Hash1(i,i+m-1)==hashs2){
printf("%d\n",i+1);
}
}
return 0;
}
双哈希字符串查重
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define LL long long
const int MAXN = 10010;
const int MAXM = 1510;
const int Base = 79;
const int MOD1 = 1e9+9;
const int MOD2 = 1e9+7;
int get_num(char x){
if('A'<=x&&x<='Z') return x-'A';
else if('a'<=x&&x<='z') return x-'a'+26;
else return x-'0'+52;
}
int n,cnt;
map<int,bool> Hash;
char s[MAXM];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s",s);
int len=strlen(s);
LL ha1=0ll,ha2=0ll;
for(int i=0;i<len;++i){
ha1=(ha1*Base+get_num(s[i]))%MOD1;
ha2=(ha2*Base+get_num(s[i]))%MOD2;
}
if(!Hash[ha1]&&!Hash[ha2]){
++cnt;
Hash[ha1]=Hash[ha2]=1;
}
}
printf("%d\n",cnt);
return 0;
}
trie
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN=3000010;
int T,n,q,num,ch[MAXN][65],cnt[MAXN];
inline int get_num(char x){
if('A'<=x&&x<='Z') return x-'A';
else if('a'<=x&&x<='z') return x-'a'+26;
else return x-'0'+52;
}
void insert(char s[]){
int l=strlen(s);
int p=0;
for(int i=0;i<l;++i){
int c=get_num(s[i]);
if(!ch[p][c]) ch[p][c]=++num;
p=ch[p][c];
++cnt[p];
}
}
int query(char s[]){
int l=strlen(s);
int p=0;
for(int i=0;i<l;++i){
int c=get_num(s[i]);
if(!ch[p][c]) return 0;
p=ch[p][c];
}
return cnt[p];
}
int main(){
scanf("%d",&T);
while(T--){
for(int i=0;i<=num;++i){
for(int j=0;j<63;++j)
ch[i][j]=0;
cnt[i]=0;
}
num=0;
scanf("%d%d",&n,&q);
char s[MAXN];
for(int i=1;i<=n;++i){
scanf("%s",s);
insert(s);
}
for(int i=1;i<=q;++i){
scanf("%s",s);
printf("%d\n",query(s));
}
}
return 0;
}
AC自动机
#include<iostream>
#include<cstring>
#include<cstdio>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define reset(a) memset(a,0,sizeof(a))
#define MAXN 20010
using namespace std;
int ch[MAXN][26],next[MAXN],mark[MAXN];
int sum[MAXN],que[MAXN<<5],pos[MAXN];
int n,cnt=1,head,tail,maxx;
char s[155][155];
void insert(char ss[],int p){
int u=1,len=strlen(ss);
rep(i,0,len-1){
int c=ss[i]-'a';
if(!ch[u][c]) ch[u][c]=++cnt;
u=ch[u][c];
}
mark[u]++; pos[p]=u;
}
void bfs(){
head=tail=0;
rep(i,0,25) ch[0][i]=1;
que[++tail]=1; next[1]=0;
while(head<tail){
int u=que[++head];
rep(i,0,25){
if(!ch[u][i])
ch[u][i]=ch[next[u]][i];
else{
que[++tail]=ch[u][i];
next[ch[u][i]]=ch[next[u]][i];
}
}
}
}
void find(char ss[]){
int u=1,len=strlen(ss),c,k;
rep(i,0,len-1){
c=ss[i]-'a';
k=ch[u][c];
while(k>1){
if(mark[k]){
sum[k]++;
if(sum[k]>maxx)
maxx=sum[k];
}k=next[k];
}
u=ch[u][c];
}
}
int main(){
scanf("%d",&n);
char S[1000100];
while(n){
reset(ch); reset(next);
reset(sum); reset(mark);
reset(pos); cnt=1; maxx=0;
for(int i=1;i<=n;i++){
scanf("%s",s[i]);
insert(s[i],i);
}
scanf("%s",S);
bfs();
find(S);
printf("%d\n",maxx);
for(int i=1;i<=n;i++)
if(sum[pos[i]]==maxx)
printf("%s\n",s[i]);
scanf("%d",&n);
}
return 0;
}