• 浅谈序列自动机


    简介

    序列自动机是一个可以快速判断字符串(t)是否是字符串(s)的子串的一个算法。

    构造

    (s)构造序列自动机,使用(Nxt_{i,j})代表从第(i)个位置开始,字符(j)出现的第一个位置。我们倒着遍历更新即可。

    	int nxt[N][27];
    	void init(char *s){
    		int l=strlen(s);
    		for(int i=0;i<26;i++) nxt[l][i]=INF;
    		for(int i=l-1;i>=0;i--){
    			for(int j=0;j<26;j++){
    				nxt[i][j]=nxt[i+1][j];
    			}
    			nxt[i][s[i]-'a']=i;
    		}
    	}
    

    查询

    设置初始指针(p)为-1,每次让(p)跳到(Nxt_{p+1,j})上面,(j)为当前查询的字符,如果(p)(INF),则说明找不到下一个字符,即(t)不是(s)的子串。

    	bool find(char *t){
    		int pos=-1;
    		int l=strlen(t);
    		for(int i=0;i<l;i++){
    			pos=nxt[pos+1][t[i]-'a'];
    			if(pos==INF) return 0;
    		}
    		return 1;
    	}
    

    模板

    struct sub_AM{
    	int nxt[N][27];
    	void init(char *s){
    		int l=strlen(s);
    		for(int i=0;i<26;i++) nxt[l][i]=INF;
    		for(int i=l-1;i>=0;i--){
    			for(int j=0;j<26;j++){
    				nxt[i][j]=nxt[i+1][j];
    			}
    			nxt[i][s[i]-'a']=i;
    		}
    	}
    	bool find(char *t){
    		int pos=-1;
    		int l=strlen(t);
    		for(int i=0;i<l;i++){
    			pos=nxt[pos+1][t[i]-'a'];
    			if(pos==INF) return 0;
    		}
    		return 1;
    	}
    }solve;
    

    Problems

    计蒜客 Subsquenece

    #include<bits/stdc++.h>
    
    using namespace std;
    const int N = 1e5+100;
    const int INF = 0x3f3f3f3f;
    char s[N];
    char t[N];
    struct sub_AM{
    	int nxt[N][27];
    	void init(char *s){
    		int l=strlen(s);
    		for(int i=0;i<26;i++) nxt[l][i]=INF;
    		for(int i=l-1;i>=0;i--){
    			for(int j=0;j<26;j++){
    				nxt[i][j]=nxt[i+1][j];
    			}
    			nxt[i][s[i]-'a']=i;
    		}
    	}
    	bool find(char *t){
    		int pos=-1;
    		int l=strlen(t);
    		for(int i=0;i<l;i++){
    			pos=nxt[pos+1][t[i]-'a'];
    			if(pos==INF) return 0;
    		}
    		return 1;
    	}
    }solve;
    int main(){
    	scanf("%s",s);
    	solve.init(s);
    	int q;
    	scanf("%d",&q);
    	while(q--){
    		scanf("%s",t);
    		if(solve.find(t)){
    			puts("YES");
    		}
    		else puts("NO");
    	}		
    	return 0;
    }
    
  • 相关阅读:
    合成反应
    poj 2229 Sumsets(dp)
    poj 2229 Sumsets(dp)
    Redis 笔记与总结3 list 类型
    大数据时代 企业要跟得上潮流
    大数据时代 企业要跟得上潮流
    企业用好大数据只需这6招
    企业用好大数据只需这6招
    企业大数据运用实战案例分享
    企业大数据运用实战案例分享
  • 原文地址:https://www.cnblogs.com/codancer/p/12232389.html
Copyright © 2020-2023  润新知