您的位置:首页 > 其它

pku 1816 Wild Words

2011-05-15 14:59 253 查看
字典树+深搜。。

这个题和hdu上的T9有点相似,不过应该比那个要稍难一点,这个需要处理?和*的情况,还要处理模式串相同的情况。。

这是我们前几天比赛的题目,当时没有做出来,开始的时没有想起来用字典树,后来队友说用字典树就写了一下。

写着写着感觉还可以,把?和*分别看成是next的第26和27,建树的时候很简单。之后查询的时候要考虑全面,

对于*进行特殊的处理,它可能是一个字符也可能是多个字符也可能没有字符。。

还有一点就是对于相同的模式串, 要标记一下。

例如

2 1

abc

abc

abc

刚开始的时候把temp->num=-1;

Insert第0个模式串的时候把当前的temp->num=0;

之后插入第一个的时候把father[1]=0;然后把temp->num=1;这样就构成了一个线性的链了。

查询结束的时候 按线性查找所有的数 都加入到数组里面,对数组排序即可。

代码:

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# define MAX 28
struct Trie{
int num;
Trie *next[MAX];
};
char keyword[10];
char str[25];
int count[400005],k,father[100005],len;
int cmp(const void *a,const void *b)
{
return *(int *)a - *(int *)b;
}
Trie *NewTrie()
{
int i;
Trie *temp=new Trie;
temp->num=-1;
for(i=0;i<MAX;i++)
temp->next[i]=NULL;
return temp;
}
void Insert(Trie *p,char s[],int ans)
{
int i;
Trie *temp=p;
i=0;
while(s[i])
{
if(s[i]>='a' && s[i]<='z')
{
if(temp->next[s[i]-'a']==NULL) temp->next[s[i]-'a']=NewTrie();
temp=temp->next[s[i]-'a'];
}
else
{
if(s[i]=='?')
{
if(temp->next[26]==NULL) temp->next[26]=NewTrie();
temp=temp->next[26];
}
else
{
if(temp->next[27]==NULL) temp->next[27]=NewTrie();
temp=temp->next[27];
}
}
i++;
}
if(temp->num==-1) temp->num=ans;
else
{
father[ans]=temp->num;
temp->num=ans;
}
}
void dfs(Trie *p,int i)
{
int j;
Trie *temp=p;
if(str[i]==0)
{
if(temp->num!=-1)
{
k++;
count[k]=temp->num;
}
while(temp->next[27]!=NULL )
{
if(temp->next[27]->num!=-1)
{
k++;
count[k]=temp->next[27]->num;
}
temp=temp->next[27];
}
return;
}

if(temp->next[str[i]-'a']!=NULL) dfs(temp->next[str[i]-'a'],i+1);
if(temp->next[26]!=NULL) dfs(temp->next[26],i+1);
if(temp->next[27]!=NULL)
{
for(j=i;j<=len;j++)
dfs(temp->next[27],j);
}

}
int main()
{
int i,n,m,j,ans;
Trie *p;
while(scanf("%d%d",&n,&m)!=EOF)
{
p=NewTrie();
for(i=0;i<=n;i++)
father[i]=i;
for(i=0;i<n;i++)
{
scanf("%s",keyword);
Insert(p,keyword,i);
}
while(m--)
{
scanf("%s",str);
len=strlen(str);
k=0;
dfs(p,0);
if(k==0) printf("Not match\n");
else
{
ans=k;
for(i=1;i<=ans;i++)
{
j=count[i];
while(father[j]!=j)
{
k++;
count[k]=father[j];
j=father[j];
}
}
qsort(count+1,k,sizeof(count[1]),cmp);
count[0]=-1;
for(i=1;i<=k;i++)
{
if(count[i]!=count[i-1])
printf("%d ",count[i]);
}
printf("\n");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: