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

AC自动机总结

时间:2019-10-13 18:34:33      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:mat   ac自动机   升级版   复杂   文本   引入   query   复杂度   暴力   

问题引入

考虑KMP问题的升级版,即有多个模式串,单个文本串。问匹配次数。

问题解决

暴力KMP

考虑对于每一个模式串建一个\(fail\)然后对于每一个模式串都和文本串暴力跑。

AC自动机

前置知识

Trie树,bfs……没什么好说的。

算法实现

我们考虑将所有的模式串放到一颗\(Trie\)树,如果匹配失败的话转移到\(fail\)指针上面去,这样子复杂度就是\(O(n)\)的了 。

唯一的问题在于\(fail\)怎么构建,直接$BFS即可。

代码实现

void insert(char *s){
    int l=strlen(s),pos=0;
    for(int i=0;i<l;i++){
        int x=s[i]-'a';
        if(!ch[pos][x])ch[pos][x]=++tot;
        pos=ch[pos][x];
    }
    siz[pos]++;
}
queue<int>Q;
void get_fail(){
    for(int i=0;i<26;i++)
        if(ch[0][i]){
            Q.push(ch[0][i]);fail[ch[0][i]]=0;
        }
    while(!Q.empty()){
        int u=Q.front();Q.pop();
        for(int i=0;i<26;i++){
            int &v=ch[u][i];
            if(v){
                fail[v]=ch[fail[u]][i];Q.push(v);
            }
            else v=ch[fail[u]][i];
        }
    }
}
int query(char *s){
    int l=strlen(s),pos=0,ans=0;
    for(int i=0;i<l;i++){
        int x=s[i]-'a';pos=ch[pos][x];
        for(int u=pos;u &&~siz[u];u=fail[u]){
            ans+=siz[u];siz[u]=-1;
        }
    }
    return ans;
}

AC自动机总结

标签:mat   ac自动机   升级版   复杂   文本   引入   query   复杂度   暴力   

原文地址:https://www.cnblogs.com/fexuile/p/11667084.html

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