当前位置:编程学习 > C/C++ >>

HDU 3065 AC自动机 裸题

#include <stdio.h>
#include <string.h>
#include <queue>
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<int> 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;
}

 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,