您的位置:首页 > 其它

POJ 1816 Wild Words

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

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

程序代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
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<iostream>
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: