’?’&&’*‘多对多代替字符匹配 Trie POJ 1816 Wild Words

来源:互联网 发布:mac关闭后台程序快捷键 编辑:程序博客网 时间:2024/05/22 17:05

http://poj.org/problem?id=1816

题意:

给出n个模式串,串中除开小写字母外,’?’代表一个字符,’*’代表可空的任意字符串,然后再给出m个字符串,问有多少个模式串可以与之匹配。


解析:
可以通过模式串建立字典树,接着根据字符串去dfs就行了。 

需要注意的就是遇到当前节点为*则还可以继续走当前结点,每次dfs要么字典树匹配深度加1,要么字符串位置加1,记录每个结点保存模式串的终点的编号,建一个邻接表储存各个结点的模式串信息。

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#define pb push_backusing namespace std;const int MAXN = 1e5 + 10;const int maxnode = 6e5 + 10;const int sigma_size = 28;bool vis[MAXN];vector<int> ans;struct Trie {    int ch[maxnode][sigma_size];    char alpha[maxnode];    vector<int> val[maxnode];    int sz;    void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); }    Trie() { clear(); }    inline int idx(char c) {        if(c == '?') return 26;        else if(c == '*') return 27;        return c - 'a';    }    void insert(char *s, int v) {        int u = 0, n = strlen(s);           for(int i = 0; i < n; i++) {            int c = idx(s[i]);            if(!ch[u][c]) {                memset(ch[sz], 0, sizeof(ch[sz]));                alpha[sz] = s[i];                val[sz].clear();                ch[u][c] = sz++;            }            u = ch[u][c];        }        val[u].pb(v);    }    void dfs(char* s, int u) {        if(*s == '\0') {            for(int i = 0; i < val[u].size(); i++) {                int tmp = val[u][i];                 if(!vis[tmp]) {                    vis[tmp] = true;                    ans.pb(tmp);                }            }            if(ch[u][27]) dfs(s, ch[u][27]);            return ;        }        int c = idx(*s);        if(ch[u][c])            dfs(s+1, ch[u][c]);        if(ch[u][26])            dfs(s+1, ch[u][26]);        if(ch[u][27]) {            dfs(s+1, ch[u][27]);            dfs(s, ch[u][27]);        }        if(alpha[u] == '*')            dfs(s+1, u);    }} trie;void output() {    sort(ans.begin(), ans.end());    printf("%d", ans[0]);    for(int i = 1; i < ans.size(); i++)        printf(" %d", ans[i]);    puts("");}char str[20];int n, m;int main() {    while(scanf("%d%d", &n, &m) != EOF) {        trie.clear();        for(int i = 0; i < n; i++) {            scanf("%s", str);            trie.insert(str, i);        }        for(int i = 0; i < m; i++) {            scanf("%s", str);            memset(vis, false, sizeof(vis));            ans.clear();            trie.dfs(str, 0);            int size = ans.size();            if(size > 0) output();            else puts("Not match");        }    }    return 0;}


0 0
原创粉丝点击