poj 1816 字典树trie+自动机的理解

?当做一个普通字符来处理,匹配遇到任何字符时都往下走

*的处理,不能在当前状态连一条连向自己的边,这样会有状态冲突,

比如

4

*

?*

*?

??

这一组,这样构造出来的会包含*?*?

*必须连向一个新的节点,匹配字符为*,这个新的节点连一条连向自己的边,在dfs匹配时一遇到*就往下走,p不增加,

在有连向自己的边的节点上,可以p+1但不往下走,也可以p+1并往下走

dfs就是在构造出来的自动机上跑

#include 
#include 
#include 
#include 
#include 
using namespace std;

struct Node
{
    vectorval;
    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;ich[nxt]==NULL)
            p->ch[nxt]=new Node();
        p=p->ch[nxt];
        if(nxt==27)
            p->star=true;
    }
    p->val.push_back(idx);
}
vectorans;
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;jval.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


你可能感兴趣的:(ACM,字符串)