码迷,mamicode.com
首页 > 其他好文 > 详细

AC自动机

时间:2020-01-22 21:34:51      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:bfs   build   文本   uil   cpp   turn   fail   匹配   oid   

构建字典图实现自动跳转,构建失配指针实现多模式匹配

\(fail\)指针表示文本串在当前节点失配后,我们应该到哪个节点去继续匹配,\(u\)\(fail\)指针指向\(v\)表示从根到\(v\)的字符串为从根到\(u\)的字符串的最长后缀,用\(bfs\)来构建\(fail\)指针

\(fail[trie[x][i]]=trie[fail[x]][i]\)

相当于在\(x\)\(fail[x]\)后面加一个字符\(i\),就构成\(fail[trie[x][i]]\)

若发现\(trie[x][i]\)不存在,则直接将其\(trie[fail[x]][i]\)赋值给它,来实现一个类似于路径压缩的操作

\(code\)

void insert(char *str)
{
    int len=strlen(str),cur=0;
    for(int i=0;i<len;++i)
    {
        int ch=str[i]-'a';
        if(!trie[cur][ch])
            trie[cur][ch]=++tot;
        cur=trie[cur][ch];
    }
    num[cur]++;
}
void build()
{
    queue<int> q;
    for(int i=0;i<26;++i)
        if(trie[0][i])
            q.push(trie[0][i]);  
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=0;i<26;++i)
        {
            int y=trie[x][i];
            if(y)
            {
                fail[y]=trie[fail[x]][i];
                q.push(y);
            }
            else trie[x][i]=trie[fail[x]][i];
        }
    }
}
int query(char *str)
{
    int len=strlen(str),cur=0,ans=0;
    for(int i=0;i<len;++i)
    {
        int ch=str[i]-'a';
        cur=trie[cur][ch];
        for(int j=cur;num[j]!=-1&&j;j=fail[j])
            ans+=num[j],num[j]=-1;
    }
    return ans;
}

AC自动机

标签:bfs   build   文本   uil   cpp   turn   fail   匹配   oid   

原文地址:https://www.cnblogs.com/lhm-/p/12229506.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!