poj 1816 (Trie + dfs)

题目链接:http://poj.org/problem?id=1816

思路:建好一颗Trie树,由于给定的模式串可能会重复,在原来定义的结构体中需要增加一个vector用来记录那些以该节点为结尾的字符串的序号,然后就是匹配的过程了,需要注意的是,对于‘?'和'*',每一次都是可以匹配的,并且对于'*',还得枚举所需要匹配的长度(从0开始)。由于最后的答案可能会有重复,一开始我没有判断时候有重复的,WA了好多次=.=!!.

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <vector>
  6 #define REP(i, a, b) for (int i = (a); i <= (b); ++i)
  7 using namespace std;
  8 
  9 const int MAN_N = (100000 + 100);
 10 struct Trie {
 11     int index;
 12     Trie *next[28];
 13     vector<int > ID; //可能会重复
 14     Trie()
 15     {
 16         index = -1;
 17         memset(next, 0, sizeof(next));
 18         ID.clear();
 19     }
 20 };
 21 
 22 Trie *root;
 23 int getID(char ch)
 24 {
 25     if (ch >= 'a' && ch <= 'z') return ch - 'a';
 26     else if (ch == '?') return 26;
 27     return 27;
 28 }
 29 void Insert(char *str, int pos)
 30 {
 31     int len = strlen(str);
 32     Trie *p = root;
 33     REP(i, 0, len - 1) {
 34         int id = getID(str[i]);
 35         if (p->next[id] == NULL) {
 36             p->next[id] = new Trie();
 37         }
 38         p = p->next[id];
 39     }
 40     p->index = pos;
 41     p->ID.push_back(pos);
 42 }
 43 int N, M;
 44 char str[22];
 45 vector<int > ans;
 46 
 47 void Check(Trie *&p)
 48 {
 49     if (p->next[27]) {
 50         if (p->next[27]->index != -1) {
 51             REP(i, 0, (int)p->next[27]->ID.size()-1) ans.push_back(p->next[27]->ID[i]);
 52         }
 53         Check(p->next[27]);
 54     }
 55 }
 56 
 57 
 58 void dfs(Trie *&p, int pos)
 59 {
 60     if (pos == N) {
 61         if (p->index != -1) {
 62             REP(i, 0, (int)p->ID.size()-1) {
 63                 ans.push_back(p->ID[i]);
 64             }
 65         }
 66         Check(p);
 67     } else {
 68         if (p->next[getID(str[pos])]) dfs(p->next[getID(str[pos])], pos + 1);
 69         if (p->next[26]) dfs(p->next[26], pos + 1);
 70         if (p->next[27]) {
 71             REP(i, pos, N) dfs(p->next[27], i);
 72         }
 73     }
 74 }
 75 
 76 
 77 int main()
 78 {
 79     cin >> N >> M;
 80     root = new Trie();
 81     REP(i, 0, N - 1) {
 82         scanf("%s", str);
 83         Insert(str, i);
 84     }
 85     REP(i, 0, M - 1) {
 86         scanf("%s", str);
 87         N = strlen(str);
 88         dfs(root, 0);
 89         if ((int)ans.size() > 0) {
 90             sort(ans.begin(), ans.end());
 91             printf("%d", ans[0]);
 92             REP(i, 1, (int)ans.size()-1) {
 93                 if (ans[i] != ans[i - 1]) printf(" %d", ans[i]);
 94             }
 95             puts("");
 96         } else
 97             puts("Not match");
 98         ans.clear();
 99     }
100     return 0;
101 }
View Code

 

posted @ 2014-05-23 18:46  ihge2k  阅读(421)  评论(0编辑  收藏  举报