?当做一个普通字符来处理,匹配遇到任何字符时都往下走
*的处理,不能在当前状态连一条连向自己的边,这样会有状态冲突,
比如
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;
}