• 字符串模板汇总


    字符串模板

    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;
    }
    
  • 相关阅读:
    枚举enum
    C# 位运算符
    运算符&和&&以及|和||区别比较
    LINQ TO JSON
    LINQ 随机排序
    .NET Core LinQ
    CSharp笔记>>>多线程
    3D旋转
    CSharp 之CSkin的使用教程
    CSharp笔记>>>多语言,注册,模态对话框返回值
  • 原文地址:https://www.cnblogs.com/66-CCF-F/p/16725911.html
Copyright © 2020-2023  润新知