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

AC自动机模板

时间:2016-08-23 06:51:07      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

推荐博客

http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html

 

模板使用的是LRJ的,这里使用了last数组,并没有补边。

last数组的含义:当你遍历到目标串T的c节点时,T[1,c]的后缀可能是模板串.所以记录下来

 

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define CLR(x) memset(x,0,sizeof x)
#define MC(x,y) memcpy(x,y,sizeof(x))  
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
#define INF 1e18
typedef pair<int,int> P;
const double eps=1e-9;
const int maxnnode=11000;
const int maxn=150+10;
const int mod=20071027;

struct AhoCorasickAutomata{
    int ch[maxnnode][26];
    int f[maxnnode];
    int val[maxnnode];
    int last[maxnnode];
    int cnt[maxn];
    int sz;
    void Init(){
        sz=1;
        CLR(ch);CLR(cnt);
    }
    int Idx(char c){return c-a;}//将模板插入Trie中 
    void Insert(char *s,int v){
        int u=0,n=strlen(s);
        for(int i=0;i<n;i++){
            int c=Idx(s[i]);
            if(!ch[u][c])
            {
                CLR(ch[sz]);
                val[sz]=0;
                ch[u][c]=sz++;
            }
            u=ch[u][c];
        }
        val[u]=v;
    }
    void Print(int j){
        if(j){
            printf("%d %d\n",j,val[j]);
            Print(last[j]);
        }
    }
    void Find(char* T){
        int n=strlen(T);
        int j=0;
        for(int i=0;i<n;i++){
            int c=Idx(T[i]);
            while(j&&!ch[j][c]) j=f[j];
            j=ch[j][c];
            if(val[j]) Print(j);
            else if(last[j]) Print(last[j]);
        }
    }
    void Getfail(){
        queue<int> q;
        f[0]=0;
        for(int c=0;c<26;c++){
            int u=ch[0][c];
            if(u){f[u]=0;q.push(u);last[u]=0;}
        }
        while(!q.empty()){
            int r=q.front();q.pop();
            for(int c=0;c<26;c++){
                int u=ch[r][c];
                if(!u) continue;
                q.push(u);
                int v=f[r];
                while(v&&!ch[v][c]) v=f[v];
                f[u]=ch[v][c];
                last[u]=val[f[u]]?f[u]:last[f[u]];
            }
        }
    }
};

AhoCorasickAutomata ac;
char tmp[maxn];

int main(){
    int n;
    scanf("%d",&n);
    ac.Init();

    for(int i=1;i<=n;i++){
        scanf("%s",tmp);
        ac.Insert(tmp,i);
    }
    ac.Getfail();
    scanf("%s",tmp);
    ac.Find(tmp);
    return 0;
}

/*
样例
5
one
two
three
four
five
oneoneonetwotwotwofourfffffiveffadfafdathree
*/

 

AC自动机模板

标签:

原文地址:http://www.cnblogs.com/byene/p/5797840.html

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