题目大意:
给出N个带通配符(?和*)的模式串, M个询问, 询问一个给你的字符串能匹配哪些模式串. 模式串长度不超过6, 询问串长度不超过20.
简要分析:
带通配符AC自动机? 不是的, 看字符串的长度都那么小, 暴力一下就可以了. 把所有模式串丢到Trie里面, *和?也作为一种转移, 对于每个询问串, 暴力dfs就可以了.
代码实现:
View Code
1 #include <cstdio>
2 #include <cstdlib>
3 #include <cstring>
4 #include <vector>
5 #include <algorithm>
6 using namespace std;
7
8 const int MAX_N = 100000 , MAX_M = 100 , P_LEN = 6 , W_LEN = 20 ;
9 int n, m;
10 char p[P_LEN + 1 ], w[W_LEN + 1 ];
11
12 #define pb push_back
13
14 namespace trie {
15 const int MAX_NODE = 200000 , SON = 28 ;
16
17 struct node_t {
18 vector < int > v;
19 node_t *son[SON];
20 node_t() { v.clear(), memset(son, 0 , sizeof (son)); }
21 } node_pool[MAX_NODE + 1 ], *node_idx = node_pool, *root = NULL;
22
23 node_t *node_alloc() {
24 return node_idx ++;
25 }
26
27 void init() {
28 root = node_alloc();
29 }
30
31 void ins( int id, char *str) {
32 node_t *pos = root;
33 while (*str) {
34 int t = *(str ++);
35 t = (t == ' ? ' ? 26 : (t == ' * ' ? 27 : t - ' a ' ));
36 if (!pos -> son[t]) pos -> son[t] = node_alloc();
37 pos = pos -> son[t];
38 }
39 pos -> v.pb(id);
40 }
41
42 vector < int > ans;
43 int sz;
44
45 void dfs( char *str, node_t *pos, int idx) {
46 if (str[idx] != 0 ) {
47 int t = str[idx] - ' a ' ;
48 if (pos -> son[t]) dfs(str, pos -> son[t], idx + 1 );
49 if (pos -> son[ 26 ]) dfs(str, pos -> son[ 26 ], idx + 1 );
50 if (pos -> son[ 27 ])
51 for ( int i = idx; i <= sz; i ++) dfs(str, pos -> son[ 27 ], i);
52 }
53 else {
54 for ( int i = 0 , rb = pos -> v.size(); i < rb; i ++) ans.pb(pos -> v[i]);
55 if (pos -> son[ 27 ]) dfs(str, pos -> son[ 27 ], idx);
56 }
57 }
58
59 void go( char *str) {
60 ans.clear();
61 sz = strlen(str);
62 dfs(str, root, 0 );
63 sort(ans.begin(), ans.end());
64 ans.resize(distance(ans.begin(), unique(ans.begin(), ans.end())));
65 if (!ans.size()) printf( " Not match\n " );
66 else {
67 for ( int i = 0 , rb = ans.size(); i < rb; i ++) printf( " %d " , ans[i]);
68 printf( " \n " );
69 }
70 }
71 }
72
73 int main(){
74 scanf( " %d%d " , &n, &m);
75 trie::init();
76 for ( int i = 0 ; i < n; i ++) {
77 scanf( " %s " , p);
78 trie::ins(i, p);
79 }
80 for ( int i = 0 ; i < m; i ++) {
81 scanf( " %s " , w);
82 trie::go(w);
83 }
84 return 0 ;
85 }