1 /****************************************************************************************************
2 Target: To realize the Aho-CorasickAutomaton
3 Author: Xue Zhonghao
4 Date: Forgotten (Before 2014-3-11 19:54:42)
5 ****************************************************************************************************/
6 #include<cstdio>
7 #include<cstdlib>
8 #include<cstring>
9 #include<queue>
10 #include<iostream>
11 using namespace std;
12
13 #define clr(a,b) memset(a, b, sizeof(a))
14 #define idx(c) (c - 'a')
15
16 const int maxnode = 10000;
17 const int sigma_size = 26;
18
19 int f[maxnode], last[maxnode];
20 int ch[maxnode][sigma_size];
21 int val[maxnode];
22 struct Trie{
23 int sz;
24 void clear(void){ sz = 1; clr(ch[0], 0); }
25 void insert(string s, int v)
26 {
27 int u = 0, n = s.length();
28 for(int i = 0; i < n; ++i){
29 int c = idx(s[i]);
30 if(!ch[u][c]){
31 clr(ch[sz], 0);
32 val[sz] = 0;
33 ch[u][c] = sz++;
34 }
35 u = ch[u][c];
36 }
37 val[u] = v;
38 }
39 };
40 void getFail(void)
41 {
42 queue<int> q;
43 f[0] = 0;
44 for(int c = 0; c < sigma_size; ++c){
45 int u = ch[0][c];
46 if(u) { f[u] = 0; q.push(u); last[u] = 0; }
47 }
48 while(!q.empty()) {
49 int r = q.front(); q.pop();
50 for(int c = 0; c < sigma_size; ++c) {
51 int u = ch[r][c];
52 if(!u) continue;
53 q.push(u);
54 int v = f[r];
55 while(v && !ch[v][c]) v = f[v];
56 f[u] = ch[v][c];
57 last[u] = (val[f[u]]) ? (f[u]) : (last[f[u]]);
58 }
59 }
60 }
61
62 void print(int j)
63 {
64 if(j){
65 cout<<j<<": "<<val[j]<<endl;
66 print(last[j]);
67 }
68 }
69
70 void find(string T)
71 {
72 int n = T.length();
73 int j = 0;
74 for(int i = 0; i < n; ++i){
75 int c = idx(T[i]);
76 while(j && !ch[j][c]) j = f[j];
77 j = ch[j][c];
78 if(val[j]) print(j);
79 else if(last[j]) print(last[j]);
80 }
81 }
82
83 int main(void)
84 {
85 Trie trie;
86 int N, V;
87 trie.clear();
88 string s, T;
89 cin>>N;
90 for(int i = 1; i <= N; ++i) cin>>s, trie.insert(s, i);
91 while(cin>>T){
92 getFail();find(T);}
93 system("pause");
94 return 0;
95 }