• 1036 : Trie图 (AC自动机)


    题目大意: 输入 n 个目标单词和一个文本串,判断文本串中是否存在某些目标单词。

    思路 赤裸裸的 AC自动机。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    #include<cmath>
    #include<map>
    using namespace std;
    #define INF 0x7fffffff
    
    int ch[1000010][26],f[1000010],last[1000010],val[1000010],nz,found;
    char s[1000000],T[1000010];
    
    void insert(){
    	int i,j,u = 0,len = strlen(s);
    	for(i=0; i<len; i++){
    		int v = s[i] - 'a';
    		if(!ch[u][v]){
    			memset(ch[nz],0,sizeof(ch[nz]));
    			val[nz] = 0;
    			ch[u][v] = nz ++;
    		}
    		u = ch[u][v];
    		val[u] = 0;
    	}
    	val[u] = 1;
    }
    
    void getFail(){
    	int i,j,n;
    	queue<int> Q;
    	while(!Q.empty())
    	    Q.pop();
    	f[0] = 0;
    	for(int c =0; c<26; c++){
    		int u = ch[0][c];
    		if(u){
    			f[u] = 0;
    			last[u] = 0;
    			Q.push(u);	
    		}
    	}
    	while(!Q.empty()){
    		int r = Q.front();
    		Q.pop();
    		for(int c=0; c<26; c++){
    			int u = ch[r][c];
    			if(!u)
    			    continue;
    			Q.push(u);
    			int v = f[r];
    			while(v && !ch[v][c])
    			    v = f[v];
    			f[u] = ch[v][c];
    			last[u] = val[f[u]] ? f[u] : last[f[u]];
    		}
    	}
    }
    
    void find(){
    	int i,j,len = strlen(T),u = 0;
    	for(i=0; i<len; i++){
    		int v = T[i] - 'a';
    		while(u && !ch[u][v]) u = f[u];
    		u = ch[u][v];
    		if(val[u]){
    			found = 1;
    			return ;
    		} 
    		else if(last[u]){
    			found = 1;
    			return ;
    		}
    	}
    }
    
    int main(){
    	int i,n;
    	while(scanf("%d",&n) == 1){
    		found = 0;
    		memset(val,0,sizeof(val));
    		memset(ch[0],0,sizeof(ch[0]));
    		nz = 1;
    		for(i=0;i<n;i++){
    			scanf("%s",s);
    			insert();
    		}
    		scanf("%s",T);
    		getFail();
    		find();
    		if(!found)
    		    printf("NO
    ");
    		else
    		    printf("YES
    ");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    拉格朗日乘数法
    线性判别分析(Linear Discriminant Analysis)
    有监督学习 和 无监督学习
    Jenkins入门知识
    vs技巧总结
    jenkins 神奇变量
    ubuntu12.04 折腾流水
    ubuntu 12.04 右上角的网络连接图标突然消失不见
    ubuntu 12.04 上网体验
    JIRA 初体验
  • 原文地址:https://www.cnblogs.com/jxgapyw/p/4782099.html
Copyright © 2020-2023  润新知