poj 1816 (Trie + dfs)

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

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

poj 1816 (Trie + dfs)
  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

 

你可能感兴趣的:(trie)