zoukankan      html  css  js  c++  java
  • ac自动机

    ac自动机

    解决的问题 :

    在一个文本串中查找多个模式串.

    模板

    https://www.luogu.com.cn/problem/P3808

    int n,ans;
    char s[N];
    
    bool vis[N];
    int tr[N][26];
    int endd[N];
    
    struct Trie {
    	int sz;
    	Trie() {
    		sz=1;
    		memset(tr[0],0,sizeof(tr[0]));
    		memset(vis,0,sizeof(vis));
    	}
    
    	void insert(char *s) {
    		int u =0,n=strlen(s);
    		for(int i=0; i<n; i++) {
    			int c = s[i] - 'a';
    			if(!tr[u][c]) {
    				memset(tr[sz],0,sizeof(tr[sz]));
    				endd[sz] = 0;
    				tr[u][c]=sz++;
    			}
    			u = tr[u][c];
    
    		}
    		endd[u]++;
    	}
    };
    
    int last[N],f[N];
    
    void print(int j) {
    	if(j && !vis[j]) {
    		ans += endd[j];
    		vis[j] = 1;
    		print(last[j]);
    	}
    }
    void build() {
    	queue<int>q;
    	f[0] = 0;
    	for(int i=0; i<26; i++) {
    		int u = tr[0][i];
    		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 = tr[r][c];
    			if(!u) {
    				tr[r][c] = tr[f[r]][c];
    				continue;
    			}
    			q.push(u);
    			int v =f[r];
    			while(v && !tr[v][c])v = f[v];
    			f[u] = tr[v][c];
    			last[u] = endd[f[u]]?f[u]:last[f[u]];
    		}
    	}
    }
    
    void find(char *s){
    	int n = strlen(s);
    	int j =0;
    	for(int i=0;i<n;i++){
    		int c = s[i] - 'a';
    		j = tr[j][c];
    		if(endd[j])print(j);
    		else if(last[j])print(last[j]); 
    	}
    }
    
    void work() {
    	scanf("%d",&n);
    	Trie trie;
    	ans = 0;
    	for(int i=1;i<=n;i++){
    		scanf("%s",s);
    		trie.insert(s);
    	}
    	build();
    	scanf("%s",s);
    	find(s);
    	printf("%d
    ",ans); 
    }
    

    查找文章中最多的模块串

    https://www.luogu.com.cn/problem/P3796

    int n,ans;
    char s[N][155];
    
    bool vis[N];
    int tr[N][26];
    int endd[N];
    int id[N];
    
    int num[N];
    
    struct Trie {
    	int sz;
    	Trie() {
    		sz=1;
    		memset(tr[0],0,sizeof(tr[0]));
    		memset(vis,0,sizeof(vis));
    	}
    
    	void insert(char *s,int fa) {
    		int u =0,n=strlen(s);
    		for(int i=0; i<n; i++) {
    			int c = s[i] - 'a';
    			if(!tr[u][c]) {
    				memset(tr[sz],0,sizeof(tr[sz]));
    				endd[sz] = 0;
    				tr[u][c]=sz++;
    			}
    			u = tr[u][c];
    
    		}
    		endd[u]++;
    		id[u] = fa;  //u这个结点对应fa字符串
    	}
    };
    
    int last[N],f[N];
    
    void print(int j) {
    	if(j && !vis[j]) {
    		ans += endd[j];
    		num[id[j]]++;  //记录个数
    //		vis[j] = 1;
    		print(last[j]);
    	}
    }
    void build() {
    	queue<int>q;
    	f[0] = 0;
    	for(int i=0; i<26; i++) {
    		int u = tr[0][i];
    		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 = tr[r][c];
    			if(!u) {
    				tr[r][c] = tr[f[r]][c];
    				continue;
    			}
    			q.push(u);
    			int v =f[r];
    			while(v && !tr[v][c])v = f[v];
    			f[u] = tr[v][c];
    			last[u] = endd[f[u]]?f[u]:last[f[u]];
    		}
    	}
    }
    
    void find(char *s) {
    	int n = strlen(s);
    	int j =0;
    	for(int i=0; i<n; i++) {
    		int c = s[i] - 'a';
    		j = tr[j][c];
    		if(endd[j])print(j);
    		else if(last[j])print(last[j]);
    	}
    }
    
    void work() {
    	while(~scanf("%d",&n) && n) {
    		Trie trie;
    		for(int i=0; i<n; i++) {
    			scanf("%s",s[i]);
    			trie.insert(s[i],i);
    			num[i] = 0;
    		}
    		build();
    		scanf("%s",s[n]);
    		find(s[n]);
    
    		int maxn = 0;
    		for(int i=0; i<n; i++) {
    			if(num[i] > maxn){
    				maxn = num[i];
    			} 
    		}
    		printf("%d
    ",maxn);
    		for(int i=0;i<n;i++){
    			if(num[i] == maxn){
    				printf("%s
    ",s[i]);
    			}
    		}
    	}
    }
    
  • 相关阅读:
    自动称重系统-3
    自动称重系统-2
    自动称重系统-1
    Qt-序列号生成器
    征战 OSG-序及目录
    Qt-QML-安卓编译问题
    OSG-OSG中的observer_ptr指针
    HZNU Training 22 for Zhejiang Provincial Competition 2020
    树上乱搞
    HZNU Training 21 for Zhejiang Provincial Competition 2020
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/14731828.html
Copyright © 2011-2022 走看看