?当做一个普通字符来处理,匹配遇到任何字符时都往下走
*的处理,不能在当前状态连一条连向自己的边,这样会有状态冲突,
比如
4
*
?*
*?
??
这一组,这样构造出来的会包含*?*?
*必须连向一个新的节点,匹配字符为*,这个新的节点连一条连向自己的边,在dfs匹配时一遇到*就往下走,p不增加,
在有连向自己的边的节点上,可以p+1但不往下走,也可以p+1并往下走
dfs就是在构造出来的自动机上跑
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <cstring> using namespace std; struct Node { vector<int>val; bool star; Node* ch[28]; Node() { val.clear();star=false; memset(ch,NULL,sizeof(ch)); } }*root; inline int pos(char c) { if(c>='a'&&c<='z') return c-'a'; else if(c=='?') return 26; else return 27; } void _insert(char* s,int idx) { Node *p=root; int len=strlen(s),nxt; for(int i=0;i<len;++i) { nxt=pos(s[i]); if(p->ch[nxt]==NULL) p->ch[nxt]=new Node(); p=p->ch[nxt]; if(nxt==27) p->star=true; } p->val.push_back(idx); } vector<int>ans; char str[1000],len; void dfs(int p,Node* u) { if(u->ch[27]) dfs(p,u->ch[27]); if(u->val.size()&&p==len) { for(int j=0;j<u->val.size();++j) ans.push_back(u->val[j]); return; } if(p>=len) return; if(u->star) dfs(p+1,u); int nxt=pos(str[p]); if(u->ch[nxt]) dfs(p+1,u->ch[nxt]); if(u->ch[26]) dfs(p+1,u->ch[26]); } int main () { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { root=new Node(); for(int i=0;i<n;++i) { scanf("%s",str); _insert(str,i); } for(int i=0;i<m;++i) { scanf("%s",str); len=strlen(str); ans.clear(); dfs(0,root); if(ans.size()==0) printf("Not match\n"); else { sort(ans.begin(),ans.end()); int num=unique(ans.begin(),ans.end())-ans.begin(); for(int j=0;j<num;++j) printf("%d ",ans[j]); puts(""); } } } return 0; }