zoukankan      html  css  js  c++  java
  • luogu3808 luogu3796 AC自动机(简单版) AC自动机(加强版)

    纪念一下我一晚上写了八遍AC自动机

    这是加强版的:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    int n, cnt[155], mp[155], len, maxn;
    char a[155][75], b[1000005];
    queue<int> d;
    struct ACzdj{
    	int s[10505][26], val[10505], lst[10505], fai[10505], u, v, siz;
    	//lst[i]是节点i沿失配指针走时遇到的第一个单词节点编号
    	void clr(){
    		siz = maxn = 0;
    		memset(s, 0, sizeof(s));
    		memset(cnt, 0, sizeof(cnt));
    		memset(val, 0, sizeof(val));
    		memset(lst, 0, sizeof(lst));
    		memset(fai, 0, sizeof(fai));
    	}
    	void ins(int k){
    		u = 0;
    		len = strlen(a[k]);
    		for(int i=0; i<len; i++){
    			v = a[k][i] - 'a';
    			if(!s[u][v])	s[u][v] = ++siz;
    			u = s[u][v];
    		}
    		if(!val[u])	val[u] = k;
    		mp[k] = val[u];
    	}
    	void getFail(){
    		for(int i=0; i<26; i++)
    			if(s[0][i])
    				d.push(s[0][i]);
    		while(!d.empty()){
    			u = d.front();
    			d.pop();
    			for(int i=0; i<26; i++){
    				v = s[u][i];
    				if(v){
    					fai[v] = s[fai[u]][i];
    					lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
    					d.push(v);
    				}
    				else	s[u][i] = s[fai[u]][i];
    			}
    		}
    	}
    	void query(){
    		u = 0;
    		len = strlen(b);
    		for(int i=0; i<len; i++){
    			u = s[u][b[i]-'a'];
    			if(val[u])	cnt[val[u]]++;
    			v = lst[u];
    			while(v){
    				cnt[val[v]]++;
    				v = lst[v];
    			}
    		}
    		for(int i=1; i<=n; i++)
    			maxn = max(maxn, cnt[i]);
    		printf("%d
    ", maxn);
    		for(int i=1; i<=n; i++)
    			if(cnt[mp[i]]==maxn)
    				printf("%s
    ", a[i]);
    	}
    }ac;
    int main(){
    	while(scanf("%d", &n)!=EOF){
    		if(!n)	break;
    		ac.clr();
    		for(int i=1; i<=n; i++){
    			scanf("%s", a[i]);
    			ac.ins(i);
    		}
    		ac.getFail();
    		scanf("%s", b);
    		ac.query();
    	}
    	return 0;
    }
    

    这是简单版的:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    using namespace std;
    char a[1000005];
    queue<int> d;
    int n;
    struct ACzdj{
    	int s[1000005][26], siz, u, v, len, val[1000005], mp[1000005], fai[1000005];
    	int cnt[1000005], lst[1000005];
    	void ins(int k){
    		u = 0;
    		len = strlen(a);
    		for(int i=0; i<len; i++){
    			v = a[i] - 'a';
    			if(!s[u][v])	s[u][v] = ++siz;
    			u = s[u][v];
    		}
    		if(!val[u])	val[u] = k;
    		mp[k] = val[u];
    	}
    	void getFail(){
    		u = 0;
    		for(int i=0; i<26; i++)
    			if(s[0][i])
    				d.push(s[0][i]);
    		while(!d.empty()){
    			u = d.front();
    			d.pop();
    			for(int i=0; i<26; i++){
    				v = s[u][i];
    				if(v){
    					fai[v] = s[fai[u]][i];
    					lst[v] = val[fai[v]]?fai[v]:lst[fai[v]];
    					d.push(v);
    				}
    				else	s[u][i] = s[fai[u]][i];
    			}
    		}
    	}
    	void query(){
    		u = 0;
    		len = strlen(a);
    		for(int i=0; i<len; i++){
    			u = s[u][a[i]-'a'];
    			if(val[u])	cnt[val[u]]++;
    			v = lst[u];
    			while(v){
    				cnt[val[v]]++;
    				v = lst[v];
    			}
    		}
    		int ans=0;
    		for(int i=1; i<=n; i++)
    			if(cnt[mp[i]])
    				ans++;
    		cout<<ans<<endl;
    	}
    }ac;
    int main(){
    	cin>>n;
    	for(int i=1; i<=n; i++){
    		scanf("%s", a);
    		ac.ins(i);
    	}
    	ac.getFail();
    	scanf("%s", a);
    	ac.query();
    	return 0;
    }
    
  • 相关阅读:
    SCRUM第一天
    第八周总结
    第7周总结
    团队项目nabcd
    人月神话1
    课堂练习之四则运算
    第六周总结
    Storm Grouping —— 流分组策略
    抓取网页内容生成Kindle电子书(转)
    浅析PageRank算法(转)
  • 原文地址:https://www.cnblogs.com/poorpool/p/7989555.html
Copyright © 2011-2022 走看看