Poj2662 Wild Words (字典树)

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

 

题意:给出两类字符串,一类为模式串,可包含小写字母、"*"、"?",另一类为匹配串,只包含小写字母;模式串中的"*"可以匹配零或多个匹配串的字母,"?"可以匹配一个任意字母,问题是给出的匹配串,都有哪些模式串可与之匹配.

 

可以用字典树来解决此题,用模式串建树,增加另外两个域表示"*"、"?"的情况,然后查找时可以根据情况进行搜索,要注意的是模式串可能有很多相同的,用并查集来记录覆盖情况.

 

204ms 排第一页去了:)

 

Code:

 

#include<stdio.h> #include<string.h> #define M 100008 typedef struct talT{ int k; talT *next[28]; }Trie; Trie SPACE[M*8]; Trie t; int n,m,e,l; int r[M]; int ans[M]; bool aa[M]; Trie *New() { return &SPACE[e++]; } void Insert(Trie *t,char *s,int k) { Trie *cur=t; int ix,f; for(f=false;*s;s++){ if(*s=='?'){ if(!cur->next[27]) cur->next[27]=New(); cur=cur->next[27]; f=false; } else if(*s=='*'){ if(f) continue; if(!cur->next[26]) cur->next[26]=New(); cur=cur->next[26]; f=true; } else{ ix=*s-'a'; if(!cur->next[ix]) cur->next[ix]=New(); cur=cur->next[ix]; f=false; } } if(cur->k) r[k]=cur->k; cur->k=k; } void Search(Trie *t,char *s) { Trie *cur=t; int ix; if(t==NULL) return ; if(*s==0&&t->k) ans[l++]=t->k; ix=*s-'a'; if(cur->next[ix]&&*s) Search(cur->next[ix],s+1); if(cur->next[27]&&*s) Search(cur->next[27],s+1); if(cur->next[26]){ for(;*s;s++) Search(cur->next[26],s); Search(cur->next[26],s); } } void Ans() { int i,j; memset(aa,false,sizeof(aa)); for(i=0;i<l;i++){ j=ans[i]; aa[j]=true; while(r[j]!=j){ aa[r[j]]=true; j=r[j]; } } for(j=1,i=0;j<=n;j++){ if(aa[j]){ printf("%d ",j-1); i=1; } } puts(i?"":"Not match"); } void Travers() { Trie *q[5120],*cur; int head,tail; head=tail=NULL; q[tail++]=&t; while(head<tail){ cur=q[head++]; printf("%d/t",cur->k); for(int ix=0;ix<27;ix++){ if(cur->next[ix]) q[tail++]=cur->next[ix]; } } } int main() { int i; char word[24]; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ r[i]=i; scanf("%s",word); Insert(&t,word,i); } //Travers(); for(i=1;i<=m;i++,l=0){ scanf("%s",word); Search(&t,word); Ans(); } return 0; }  

你可能感兴趣的:(Poj2662 Wild Words (字典树))