HDU 2222 — Keywords Search

来源:互联网 发布:雅思测试软件 编辑:程序博客网 时间:2024/05/19 15:39

原题:http://acm.hdu.edu.cn/showproblem.php?pid=2222

题意:

给出n个模板以及文本,问文本中出现了多少个模板;


思路:

要注意有重复的模板,也是要算数的;

用val数组来计算每种模板的个数;用vis数组来表示单词的节点;


#include<cstdio>#include<queue>#include<cstring>#include<string>using namespace std;const int maxnode = 500005;const int sigma_size=26;int ans;struct AC_Automata{    int ch[maxnode][sigma_size];    int val[maxnode];    bool vis[maxnode];    int f[maxnode];    int last[maxnode];    int sz;    void init()    {        sz = 1;        memset(ch[0], 0, sizeof(ch[0]));        memset(vis, false, sizeof vis);    }    void insert(char *s)    {        int n = strlen(s), u = 0;        for(int i = 0;i<n;i++)        {            int id = s[i]-'a';            if(ch[u][id] == 0)            {                ch[u][id] = sz;                memset(ch[sz], 0, sizeof(ch[sz]));                val[sz++] = 0;            }            u = ch[u][id];        }        val[u]++;        vis[u] = true;    }    void print(int i)    {        if(val[i])        {        if(vis[i])        {        vis[i] = false;        ans+=val[i];        }            print(last[i]);        }    }    void find(char *s)    {        int n = strlen(s), j = 0;        for(int i = 0;i<n;i++)        {            int id = s[i]-'a';            while(j && ch[j][id] == 0) j = f[j];            j = ch[j][id];            if(val[j]) print(j);            else if(val[last[j]]) print(last[j]);        }    }    void getFail()    {        queue<int>q;        last[0] = f[0] = 0;        for(int i = 0;i<sigma_size;i++)        {            int u = ch[0][i];            if(u)            {                f[u] = last[u] = 0;                q.push(u);            }        }        while(!q.empty())        {            int r = q.front(); q.pop();            for(int i = 0;i<sigma_size;i++)            {                int u = ch[r][i];                if(!u) continue;                q.push(u);                int v = f[r];                while(v && ch[v][i] == 0) v = f[v];                f[u] = ch[v][i];                last[u] = val[f[u]]? f[u]:last[f[u]];            }        }    }};AC_Automata ac;char word[55];char txt[1000005];int main(){    int n, cas;    scanf("%d", &cas);    while(cas--)    {    ans = 0;    scanf("%d\n", &n);        ac.init();        for(int i = 1;i<=n;i++)        {            scanf("%s", word);            ac.insert(word);        }        ac.getFail();        scanf("%s", txt);        ac.find(txt);        printf("%d\n", ans);    }    return 0;}


0 0