模式搜索
?:匹配任何字符
*:匹配任意个字符,包括零个
建立模式串的字典树,用并查集合并相同模式串
查询的时候深搜任何可能
#include<cstdio> #include<algorithm> #include<cstring> #define MAXN 100010 using namespace std; int n,m; struct Trie { int i; Trie *a[28]; }; Trie root; char p[7],s[22]; int set[MAXN]; bool mat[MAXN]; void Insert(Trie *rt,int k,int j) { int i,t; if(p[j]=='\0') { if(rt->i>-1) set[k]=set[rt->i]; else rt->i=k; return; } if (p[j]=='*') t=27; else if(p[j]=='?') t=26; else t=p[j]-'a'; if(!rt->a[t]) { rt->a[t]=new Trie; for(i=0;i<28;i++) rt->a[t]->a[i]=NULL; rt->a[t]->i=-1; } Insert(rt->a[t],k,j+1); } void Query(Trie *rt,int j) { if(rt->a[27]&&rt->a[27]->i>-1) mat[rt->a[27]->i]=true; if(s[j]=='\0') { if(rt->i>-1) mat[rt->i]=true; return ; } if(rt->a[s[j]-'a']) Query(rt->a[s[j]-'a'],j+1); if(rt->a[26]) Query(rt->a[26],j+1); if(rt->a[27]) for(int i=j;s[i]!='\0';i++) Query(rt->a[27],i); } int main() { int i,j,k; scanf("%d%d",&n,&m); root.i=-1; for(i=0;i<28;i++) root.a[i]=NULL; for(i=0;i<n;i++) { set[i]=i; scanf("%s",p); for(j=k=0;p[j]!='\0';j++) if(!(p[j]=='*'&&p[j+1]=='*')) p[k++]=p[j]; p[k]='\0'; Insert(&root,i,0); } for(i=0;i<m;i++) { scanf("%s",s); memset(mat,false,sizeof(mat)); Query(&root,0); for(j=k=0;j<n;j++) if(mat[j]||mat[set[j]]) mat[j]=true,k++; if(!k) puts("Not match"); else { for(j=0;j<n;j++) if(mat[j]) printf("%d ",j); putchar('\n'); } } return 0; }