HDU 3065 AC自动机 裸题

2014-11-23 23:24:37 · 作者: · 浏览: 6
#include 
#include 
#include 
using namespace std;

#define N 2000100
#define maxnode 50010
#define sigma_size 26
struct node{
	char name[55];
	int num;
}S[1101];
struct Trie{
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int f[maxnode];
	int sz;
	void init(){
		sz=1;
		memset(ch,0,sizeof(ch));
		memset(val,0,sizeof(val));
		memset(f,0,sizeof(f));
		val[0] = 0;
	}
	int idx(char c){
		return c-'A';
	}

	void Creat(char *s, int num){  
		int u = 0, len = strlen(s);  
		for(int i = 0; i < len; i++){  
			int c = idx(s[i]);
			if(!ch[u][c]) ch[u][c] = sz++; 
			u = ch[u][c];
		}  
		val[u] = num ; //u若是单词结尾则为 +1
	}  

	int find(char *T){
		int len = strlen(T);
		int j = 0;
		for(int i = 0; i < len; i++){
			if(T[i]<'A' || T[i]>'Z'){ j = 0; continue;}
			int c = idx(T[i]);
			j = ch[j][c];
			int temp = j;
			while(temp && val[temp]){
				S[ val[temp] ].num ++;	
				temp = f[ temp ];
			}
		}

		return 0;
	}

	void getFail(){
		queue
q; //初始化队列 for(int c = 0; c < sigma_size; c++) if(ch[0][c])q.push(ch[0][c]); while(!q.empty()){ int r = q.front(); q.pop(); for(int c = 0; c < sigma_size; c++){ int u = ch[r][c]; if(!u){ ch[r][c] = ch[f[r]][c]; continue; } q.push(u); int v = f[r]; while(v && !ch[v][c]) v = f[v]; //沿失配边追溯到可以匹配的(非原点)位置 f[u] = ch[v][c]; } } } }; Trie ac; char S1[N]; int main(){ int n; while(~scanf("%d",&n)){ ac.init(); for(int i = 1; i <= n; i++){ scanf("%s",S[i].name); S[i].num = 0; ac.Creat(S[i].name, i); } ac.getFail(); scanf("%s",S1); ac.find(S1); for(int i = 1; i <= n; i++) if(S[i].num) printf("%s: %d\n",S[i].name, S[i].num); } return 0; }