POJ 1816 Wild Words

      这道题用字典树来做。首先将给的模式串建一颗字典树,每个节点包含28个孩子指针,节点是那些模式串的结尾,为了方便,还包括它的父母的指针这些信息;然后再对读入的串进行配对,判断这个串的字符是否在树中或树中有'?'或'*',都进行递归;注意为'*'时,串从这个位置往后都要在此位置进行递归。

      这个题目比较棘手的地方:一是每个节点的信息;二是树中出现'*'号该如何递归。

程序代码:

#include #include #include #include #include using namespace std; #define MAXN 28 typedef struct TrieNode{ bool yes; int num[1000]; int con; struct TrieNode *pre; struct TrieNode *next[MAXN]; }TrieNode, *TriePointer; int m, n, cnt, allocp = 0, Array[1000010]; TrieNode memory[100010]; TriePointer CreatTrieNode() { TriePointer p; p = &memory[allocp++]; p->yes = false; p->pre = NULL; p->con = 0; for(int i = 0; i < MAXN; i++) p->next[i] = NULL; return p; } void InsertTrie(TriePointer *pRoot, string s, int num) { TriePointer p; if(!(p = *pRoot)) p = *pRoot = CreatTrieNode(); for(int i = 0, k; i < s.size(); i++){ if(s[i] == '?') k = 26; else if(s[i] == '*') k = 27; else k = s[i] - 'a'; if(!p->next[k]) p->next[k] = CreatTrieNode(); p->next[k]->pre = p; p = p->next[k]; } p->yes = true; p->num[(p->con)++] = num; while(p && p->pre && p == p->pre->next[27]){ p->pre->yes = true; p->pre->num[(p->pre->con)++] = num; p = p->pre; } } void SearchTire(TriePointer p, string s, int cur) { if(cur == s.size()){ if(p->yes){ for(int i = 0; i < p->con; i++) Array[cnt++] = p->num[i]; } return ; } int k = s[cur] - 'a'; if(p->next[k]) SearchTire(p->next[k], s, cur + 1); if(p->next[26]) SearchTire(p->next[26], s, cur + 1); if(p->next[27]){ int temp = cur; while(temp <= s.size()){ SearchTire(p->next[27], s, temp); temp++; } } } int main() { //freopen("input.txt", "r", stdin); scanf("%d %d", &m, &n); string input; TriePointer root = NULL; for(int i = 0; i < m; i++){ cin>>input; InsertTrie(&root, input, i); } for(int i = 0; i < n; i++){ cin>>input; cnt = 0; memset(Array, 0, sizeof(Array)); SearchTire(root, input, 0); sort(Array, Array + cnt); if(cnt){ printf("%d", Array[0]); for(int j = 1; j < cnt; j++){ if((j && Array[j] != Array[j - 1])){ printf(" %d", Array[j]); } } printf("/n"); }else printf("Not match/n"); } return 0; }  

附字典树的简单操作的模板:

#include using namespace std; #define MAXN 26 typedef struct TrieNode{ int nCount; struct TrieNode *next[MAXN]; }TrieNode, *TriePointer; TrieNode memory[1000000]; int allocp = 0; void InitTrieRoot(TriePointer *pRoot) { *pRoot = NULL; } TriePointer CreatTrieNode() { TriePointer p; p = &memory[allocp++]; p->nCount = 1; for(int i = 0; i < MAXN; i++){ p->next[i] = NULL; } return p; } void InsertTrie(TriePointer *pRoot, string s) { TriePointer p; if(!(p = *pRoot)) p = *pRoot = CreatTrieNode(); for(int i = 0, k; i < s.size(); i++){ k = s[i] - 'a'; if(p->next[k]) p->next[k]->nCount++; else p->next[k] = CreatTrieNode(); p = p->next[k]; } } int SearchTire(TriePointer *pRoot, string s) { TriePointer p; if(!(p = *pRoot)) p = *pRoot = CreatTrieNode(); for(int i = 0, k; i < s.size(); i++){ k = s[i] - 'a'; if(!p->next[k]) return 0; else p = p->next[k]; } return p->nCount; }  

你可能感兴趣的:(数据结构)