AC自动机入门题目~

View Code
1 #include <cstdio>
2 #include <cstring>
3 #include <vector>
4 #include <algorithm>
5
6 usingnamespace std;
7
8 constint NS =128;
9 constint MAXDL =256;
10 constint MAXWL =10240;
11 constint MAXN =100000;
12 constint MAXD =512;
13 constint MAXW =1024;
14
15 struct TRIE
16 {
17 int lable;
18 TRIE * fail;
19 TRIE * son[NS];
20 TRIE()
21 {
22 lable =-1;
23 fail = NULL;
24 for (int i =0;i < NS;i++)
25 son[i] = NULL;
26 }
27 };
28
29 TRIE * queue[MAXN];
30
31 bool vis[MAXW][MAXD];
32
33 char web[MAXWL];
34
35 void TrieInsert(char* word,int id,TRIE * root)
36 {
37 char* key;
38 TRIE * tmp;
39
40 key = word;
41 tmp = root;
42
43 while (*key)
44 {
45 int idx =*key++;
46 if (tmp->son[idx] == NULL) tmp->son[idx] =new TRIE();
47 tmp = tmp->son[idx];
48 }
49 tmp->lable = id;
50 }
51
52 void getFail(TRIE * root)
53 {
54 int qh =-1;
55 int qe =0;
56
57 queue[0] = root;
58 root->fail = NULL;
59
60 while (qh != qe)
61 {
62 qh++;
63
64 TRIE * tmp = queue[qh];
65
66 for (int i =0;i < NS;i++)
67 if (tmp->son[i])
68 {
69 if (tmp == root) tmp->son[i]->fail = root;
70 else
71 {
72 TRIE * p = tmp->fail;
73 while (p)
74 {
75 if (p->son[i])
76 {
77 tmp->son[i]->fail = p->son[i];
78 break;
79 }
80 p = p->fail;
81 }
82 if (p == NULL) tmp->son[i]->fail = root;
83 }
84
85 qe++;
86 queue[qe] = tmp->son[i];
87 }
88 }
89 }
90
91 bool TrieFind(char* word,int id,TRIE * root)
92 {
93 char* key;
94 TRIE * tmp;
95 vector<int> bd;
96
97 key = word;
98 tmp = root;
99 bd.clear();
100
101 while (*key)
102 {
103 int idx =*key++;
104 while (tmp->son[idx] == NULL && tmp != root) tmp = tmp->fail;
105 tmp = tmp->son[idx] == NULL ? root : tmp->son[idx];
106 TRIE * p = tmp;
107 while (p != root && p->lable !=-1&&!vis[id][p->lable])
108 {
109 bd.push_back(p->lable);
110 vis[id][p->lable] =true;
111 p = p->fail;
112 }
113 }
114
115 if (bd.size() ==0) returnfalse;
116
117 printf("web %d:",id);
118
119 sort(bd.begin(),bd.end());
120
121 int size = bd.size();
122
123 for (int i =0;i < size;i++)
124 printf(" %d",bd[i]);
125 printf("\n");
126
127 return size >0;
128 }
129
130 void TrieDelete(TRIE * root)
131 {
132 for (int i =0;i < NS;i++)
133 if (root->son[i])
134 TrieDelete(root->son[i]);
135 delete(root);
136 }
137
138 int main()
139 {
140 int dnum;
141 int wnum;
142 int total;
143 char word[MAXDL];
144
145 while (scanf("%d",&dnum) ==1)
146 {
147 total =0;
148 memset(vis,false,sizeof(vis));
149
150 TRIE * root =new TRIE();
151
152 for (int i =0;i < dnum;i++)
153 {
154 scanf("%s",word);
155 TrieInsert(word,i +1,root);
156 }
157
158 getFail(root);
159
160 scanf("%d",&wnum);
161 for (int i =0;i < wnum;i++)
162 {
163 scanf("%s",web);
164 if (TrieFind(web,i +1,root)) total++;
165 }
166 printf("total: %d\n",total);
167
168 TrieDelete(root);
169 }
170 return0;
171 }