1. 程式人生 > >hdu2222(ac自動機模板)

hdu2222(ac自動機模板)

har isp truct itl color 樹節點 namespace print 好的

先推薦兩篇寫的很好的ac自動機blog:

http://blog.csdn.net/creatorx/article/details/71100840

http://blog.csdn.net/niushuai666/article/details/7002823

正題

題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=2222

題意: 給出 n 個模式串以及一個 主串, 問有多少個模式串在主串中出現過

思路: ac自動機模板題

代碼:

技術分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string
.h> 4 #include <queue> 5 using namespace std; 6 7 const int MAXN = 5e5 + 10; 8 9 struct Trie{ 10 int next[MAXN][26], fail[MAXN], end[MAXN]; 11 int root, L; 12 int newnode(){//初始化字典樹節點 13 for(int i = 0; i < 26; i++){ 14 next[L][i] = -1; 15 } 16 end[L++] = 0
; 17 return L - 1; 18 } 19 void init(){//初始化字典樹根節點 20 L = 0; 21 root = newnode(); 22 } 23 void insert(char buf[]){//往字典樹中插入一個單詞 24 int len = strlen(buf); 25 int now = root; 26 for(int i = 0; i < len; i++){ 27 if(next[now][buf[i] -
a] == -1) next[now][buf[i] - a] = newnode(); 28 now = next[now][buf[i] - a]; 29 } 30 end[now]++; 31 } 32 void build(){ //構造fail數組 33 queue<int> Q; 34 fail[root] = root; 35 for(int i = 0; i < 26; i++){ 36 if(next[root][i] == -1) next[root][i] = root; 37 else{ 38 fail[next[root][i]] = root; 39 Q.push(next[root][i]); 40 } 41 } 42 while(!Q.empty()){ 43 int now = Q.front(); 44 Q.pop(); 45 for(int i = 0; i < 26; i++) 46 if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; 47 else{ 48 fail[next[now][i]] = next[fail[now]][i]; 49 Q.push(next[now][i]); 50 } 51 } 52 } 53 int query(char buf[]){ 54 int len = strlen(buf); 55 int now = root; 56 int res = 0; 57 for(int i = 0; i < len; i++){ 58 now = next[now][buf[i] - a]; 59 int temp = now; 60 while(temp != root){ 61 res += end[temp]; 62 end[temp] = 0; // 每個模式串只算一次,所以清0 63 temp = fail[temp]; 64 } 65 } 66 return res; 67 } 68 void debug(){ 69 for(int i = 0; i < L; i++){ 70 printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]); 71 for(int j = 0; j < 26; j++){ 72 printf("%2d",next[i][j]); 73 } 74 printf("]\n"); 75 } 76 } 77 }; 78 79 Trie ac; 80 char buf[MAXN << 1]; 81 82 int main(void){ 83 int t, n; 84 scanf("%d", &t); 85 while(t--){ 86 ac.init(); 87 scanf("%d", &n); 88 for(int i = 0; i < n; i++){ 89 scanf("%s", buf); 90 ac.insert(buf); 91 } 92 ac.build(); 93 scanf("%s", buf); 94 printf("%d\n", ac.query(buf)); 95 } 96 return 0; 97 }
View Code

hdu2222(ac自動機模板)