【AC自动机】HDU 2222 Keywords Search 裸题

来源:互联网 发布:java监控系统日志抓取 编辑:程序博客网 时间:2024/06/05 03:01

题意:给出的n个单词,出现在T中的个数。

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include <string>#include <iostream>#include <algorithm>using namespace std;#include <queue>#include <stack>#include <vector>#include <deque>#include <set>#include <map>#define cler(arr, val)    memset(arr, val, sizeof(arr))#define IN     freopen ("in.txt" , "r" , stdin);#define OUT  freopen ("out.txt" , "w" , stdout);typedef long long  LL;const int MAXN = 1000006;//点数的最大值const int MAXM = 20006;//边数的最大值const int INF = 11521204;const int mod=1000000007;#define maxnode 250001#define sigma_size 26int ans;struct Trie{    int ch[maxnode][sigma_size];    int val[maxnode];    //该单词在模式串中出现的次数    int last[maxnode];    int f[maxnode];      //失配数组    int num[maxnode];    //该单词出现在文本串的次数    int pre[maxnode];    //该单词的前驱    int len[maxnode];    //以该单词结尾的单词长度    int Char[maxnode];   //该单词对应的字母    int sz;    void init()    {        sz=1;        memset(ch,0,sizeof(ch));        memset(val, 0, sizeof(val));        memset(f,0,sizeof(f));        memset(last,0,sizeof(last));    //记录该节点前一个节点是谁        memset(len, 0, sizeof(len));    }    int idx(char c)    {        return c-'a';    }    int insert(char *s)    {        int u = 0;        for(int i = 0; s[i] ; i++)        {            int c = idx(s[i]);            if(!ch[u][c])                ch[u][c] = sz++;            u = ch[u][c];        }        val[u] ++;        return u;    }    void getFail()    {        queue<int> q;        for(int i = 0; i<sigma_size; i++)            if(ch[0][i]) q.push(ch[0][i]);        while(!q.empty())        {            int r = q.front();            q.pop();            for(int c = 0; c<sigma_size; c++)            {                int u = ch[r][c];                if(!u)continue;                q.push(u);                int v = f[r];                while(v && ch[v][c] == 0)                    v = f[v]; //沿失配边走上去 如果失配后有节点 且 其子节点c存在则结束循环                f[u] = ch[v][c];                last[u] = val[f[u]] ? f[u] : last[f[u]];            }        }    }    void find(char *T)    {        int u = 0;        for(int i = 0; T[i] ; i++)        {            int c = idx(T[i]);            while(u && ch[u][c]==0)                u = f[u];            u = ch[u][c];            int temp = u;            while(temp && val[temp])  //沿失配边走 || 若沿失配边走时一定要节点为单词结尾则改成while(temp && val[temp])            {                ans+=val[temp];                val[temp]=0;//出现后要清0                temp = f[temp];            }        }        return ;    }} ac;char s[1000010];int main(){    int t,n;   // IN;    scanf("%d",&t);    while(t--)    {        ac.init();        scanf("%d",&n);        for(int i=0; i<n; i++)        {            scanf("%s",s);            ac.insert(s);        }        ac.getFail();        scanf("%s",s);        ans=0;        ac.find(s);        printf("%d\n",ans);    }    return 0;}


0 0