题目链接:http://poj.org/problem?id=1816
思路:建好一颗Trie树,由于给定的模式串可能会重复,在原来定义的结构体中需要增加一个vector用来记录那些以该节点为结尾的字符串的序号,然后就是匹配的过程了,需要注意的是,对于‘?'和'*',每一次都是可以匹配的,并且对于'*',还得枚举所需要匹配的长度(从0开始)。由于最后的答案可能会有重复,一开始我没有判断时候有重复的,WA了好多次=.=!!.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }