您的位置:首页 > 其它

POJ 1816 Wild Words

2012-03-10 21:05 316 查看
题目大意:

给出N个带通配符(?和*)的模式串, M个询问, 询问一个给你的字符串能匹配哪些模式串. 模式串长度不超过6, 询问串长度不超过20.

简要分析:

带通配符AC自动机? 不是的, 看字符串的长度都那么小, 暴力一下就可以了. 把所有模式串丢到Trie里面, *和?也作为一种转移, 对于每个询问串, 暴力dfs就可以了.

代码实现:

View Code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX_N = 100000, MAX_M = 100, P_LEN = 6, W_LEN = 20;
int n, m;
char p[P_LEN + 1], w[W_LEN + 1];

#define pb push_back

namespace trie {
const int MAX_NODE = 200000, SON = 28;

struct node_t {
vector <int> v;
node_t *son[SON];
node_t() { v.clear(), memset(son, 0, sizeof(son)); }
} node_pool[MAX_NODE + 1], *node_idx = node_pool, *root = NULL;

node_t *node_alloc() {
return node_idx ++;
}

void init() {
root = node_alloc();
}

void ins(int id, char *str) {
node_t *pos = root;
while (*str) {
int t = *(str ++);
t = (t == '?' ? 26 : (t == '*' ? 27 : t - 'a'));
if (!pos -> son[t]) pos -> son[t] = node_alloc();
pos = pos -> son[t];
}
pos -> v.pb(id);
}

vector <int> ans;
int sz;

void dfs(char *str, node_t *pos, int idx) {
if (str[idx] != 0) {
int t = str[idx] - 'a';
if (pos -> son[t]) dfs(str, pos -> son[t], idx + 1);
if (pos -> son[26]) dfs(str, pos -> son[26], idx + 1);
if (pos -> son[27])
for (int i = idx; i <= sz; i ++) dfs(str, pos -> son[27], i);
}
else {
for (int i = 0, rb = pos -> v.size(); i < rb; i ++) ans.pb(pos -> v[i]);
if (pos -> son[27]) dfs(str, pos -> son[27], idx);
}
}

void go(char *str) {
ans.clear();
sz = strlen(str);
dfs(str, root, 0);
sort(ans.begin(), ans.end());
ans.resize(distance(ans.begin(), unique(ans.begin(), ans.end())));
if (!ans.size()) printf("Not match\n");
else {
for (int i = 0, rb = ans.size(); i < rb; i ++) printf("%d ", ans[i]);
printf("\n");
}
}
}

int main(){
scanf("%d%d", &n, &m);
trie::init();
for (int i = 0; i < n; i ++) {
scanf("%s", p);
trie::ins(i, p);
}
for (int i = 0; i < m; i ++) {
scanf("%s", w);
trie::go(w);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: