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

[模板]AC自动机(1)

时间:2018-08-19 01:04:05      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:模式   \n   turn   ++   ring   文本   return   scanf   inline   

题目描述

给定一个文本串和多个模式串,求有几个模式串出现在文本串中

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000005

char s[MAXN];
int N;
struct queue{
    int que[MAXN];int head,tail;
    queue():head(1),tail(0){}
    inline void pop(){head++;}
    inline int front(){return que[head];}
    inline void push(int x){que[++tail]=x;}
    inline bool empty(){return head>tail;}
}q;
struct Auto{
    
    int trie[26][MAXN],val[MAXN],fail[MAXN],tot;
    Auto():tot(0){}

    inline void ins(){
        int _next = 0;int len = std::strlen(s);
        for(register int i=0;i<len;++i){
            int c = s[i]-'a';
            if(!trie[c][_next])trie[c][_next] = ++tot;
            _next = trie[c][_next];
        }
        val[_next]++;
    }

    inline void make_fail(){
        for(register int i=0;i<26;++i){
            if(trie[i][0]){
                q.push(trie[i][0]);
                fail[trie[i][0]] = 0;
            }
        }
        while(!q.empty()){
            int u = q.front();q.pop();
            for(register int i=0;i<26;++i){
                if(trie[i][u]){
                    q.push(trie[i][u]);
                    fail[trie[i][u]] = trie[i][fail[u]];
                }
                else trie[i][u] = trie[i][fail[u]];
            }
        }
    }

    inline int find(){
        int ans = 0;int len = std::strlen(s);int _next = 0;
        for(register int i=0;i<len;++i){
            _next = trie[s[i]-'a'][_next];
            for(register int pos=_next;pos&&val[pos]!=-1;pos=fail[pos]){
                ans+=val[pos];
                val[pos] = -1;
            }
        }
        return ans;
    }
}AC;

int main(){

    scanf("%d\n",&N);
    for(register int i=1;i<=N;++i){
        scanf("%s",s);
        AC.ins();
    }
    AC.make_fail();
    scanf("%s",s);
    int ans = AC.find();
    printf("%d",ans);
    return 0;
}

[模板]AC自动机(1)

标签:模式   \n   turn   ++   ring   文本   return   scanf   inline   

原文地址:https://www.cnblogs.com/Neworld2002/p/9499332.html

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