AC自动机模板(多模式匹配)

来源:互联网 发布:淘宝买家v3会员是几钻 编辑:程序博客网 时间:2024/05/21 19:31
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;//ac_automaton algorithmconst int MAXNODE = 550000;const int SIGMA_SIZE = 26;int fail[MAXNODE]; //失配数组int last[MAXNODE]; //后缀链接int ans;//构造trieint ch[MAXNODE][SIGMA_SIZE];  //将单词存储在ch中int val[MAXNODE];             //每个单词出现的个数int sz;                       //节点编号void init(){    ans = 0;    sz = 1;    memset(ch[0], 0, sizeof(ch[0]));}void insert(char *s){    int u = 0;    int len = strlen(s);    for(int i = 0; i < len; ++i)    {        int c = s[i] - 'a';        if(!ch[u][c])        {            memset(ch[sz], 0, sizeof(ch[sz]));            val[sz] = 0;            ch[u][c] = sz++;        }        u = ch[u][c];    }    val[u]++;}//计算last后缀链接void getFail(){    queue<int> q;    fail[0] = 0;    for(int c = 0; c < SIGMA_SIZE; c++)    {        int u = ch[0][c];        if(u)        {            fail[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){ ch[r][c] = ch[fail[r]][c]; continue;}            q.push(u);            int v = fail[r];            while(v && !ch[v][c]) v = fail[v];            fail[u] = ch[v][c];            last[u] = val[fail[u]] ? fail[u] : last[fail[u]];        }        //cout << last[r] <<endl;    }}void solve(int j){    //cout << j <<endl;    if(!j) return;    if(val[j])    {        ans += val[j];        val[j] = 0;    }    solve(last[j]);}void find(char* T){    int len = strlen(T),j = 0;    getFail();    for(int i = 0; i < len; i++)    {        j = ch[j][T[i] - 'a'];        //cout << val[j] <<endl;        if(val[j]) solve(j);        else if(last[j]) solve(last[j]);    }}