码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2896 AC自动机

时间:2015-08-05 00:29:25      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

//	hdu 2896 AC自动机
//
//	题目大意:
//		
//		给你n个短串,然后给你q串长字符串,要求每个长字符串中
//	是否出现短串,出现的短串各是什么
//
//	解题思路:
//		
//		AC自动机,插入单词,构建自动机,然后查询就可以了。
//
//	感悟:
//
//		哎,自己AC自动机果然刚学,还只会个模板,自动机构没构建
//	都不知道。。。继续加油吧~~~FIGHTING!



#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

const int MAX_NODE = 200000;

const int SIGMA_SIZE = 131;

struct Aho_Corasick{

	int ch[MAX_NODE][SIGMA_SIZE];
	int val[MAX_NODE];
	int cnt[508];
	int sz;
	int last[MAX_NODE];
	int f[MAX_NODE];

	void clear(){
		memset(cnt,0,sizeof(cnt));
	}

	void init(){
		sz = 1;
		memset(ch[0],0,sizeof(ch[0]));
		val[0] = 0;
	}

	int idx(char c){
		return c - ‘a‘;
	}

	void insert(char *s,int v){
		int u = 0;
		int n = strlen(s);
		for (int i=0;i<n;i++){
			//int c = idx(s[i]);
			int c = s[i];
			if (!ch[u][c]){
				memset(ch[sz],0,sizeof(ch[sz]));
				val[sz] = 0;
				ch[u][c] = sz++;
			}
			u = ch[u][c];
		}
		val[u] = v;
	}

	void getfail(){
		queue<int> que;
		for (int c = 0; c < SIGMA_SIZE ; c++){
			int u = ch[0][c];
			if (u){
				que.push(u);
				last[u] = 0;
				f[u] = 0;
			}
		}
		while(!que.empty()){
			int r = que.front();
			que.pop();
			for (int c = 0; c < SIGMA_SIZE ; c++){
				int u = ch[r][c];
				if (!u)
					continue;
				que.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 get_cnt(int u){
		if (u){
			cnt[val[u]]++;
			get_cnt(last[u]);
		}
	}

	void query(char *s){
		int u = 0;
		int n = strlen(s);
		for (int i=0;i<n;i++){
			//char c = idx(s[i]);
			char c = s[i];
			while( u && !ch[u][c])
				u = f[u];

			u = ch[u][c];

			if (val[u]){
				get_cnt(u);
			}
			else if (last[u]){
				get_cnt(last[u]);
			}
		}
	}

}ac;

char str[10009];

int n;

void print(int x,int &num){
	int flag = 0;
	for (int i=1;i<=n;i++){
		if (ac.cnt[i]){
			flag = 1;
			break;
		}
	}
	if (!flag)
		return;
	
	printf("web %d:",x);
	
	for (int i=1;i<=n;i++){
		if (ac.cnt[i]){
			printf(" %d",i);
		}
	}
	puts("");
	num++;

}

void input(){
	ac.init();
	for (int i=1;i<=n;i++){
		scanf("%s",str);
		ac.insert(str,i);
	}
	int q;
	int num = 0;
	ac.getfail();
	scanf("%d",&q);
	int x = 1;
	for (int i=1;i<=q;i++){
		scanf("%s",str);
		ac.clear();
		ac.query(str);
		print(i,num);
	}
	printf("total: %d\n",num);
}

int main(){
	//freopen("1.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		input();
	}
}

 

hdu 2896 AC自动机

标签:

原文地址:http://www.cnblogs.com/KingJourney/p/4703320.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!