HDU2222 Keywords Search 题解&代码

题意:多组数据,每组数据有n个字符串作为字典,然后给出另外一个字符串,询问这个新的字符串中有几个字典中的单词。
多个匹配串对单字符串匹配,AC自动机是标准解法,算是测试模板了【笑
然而RE了一发WA了一发…没看清数据范围

对于字典中的字符串建立trie树和fail指针,然后对待匹配串匹配即可
有一些奇怪的小细节譬如字典中可能有多个相同字符串,以及判重问题…恩还是很好解决的嘛

#include 
#include 
#include 
using namespace std;
const int maxn = 500005;
const int maxm = 26;
int T, n, tot, ans, temp;
int ch[maxn][maxm], fail[maxn], flag[maxn], q[maxn], vis[maxn];
char s[maxn*2];
int cal(char c)
{
    return c-'a';
}
void newnode(int x,int temp)
{
    if(temp!=-1) ch[x][temp] = ++tot;
    for(int i = 0; i < maxm; i++)
        ch[tot][i]=0;
    flag[tot]=0;
    fail[tot]=0;
}
void addtrie(char s[])
{
    int x = 0, p = 0;
    int len = strlen(s);
    while( p < len )
    {
        temp=cal(s[p]);
        if( !ch[x][temp] ) newnode(x, temp);
            x = ch[x][temp];
            p++;
        }
        flag[x]++;
}
void getfail(void)
{
    int h = 0, t = 0;
        for(int i = 0; i < maxm; i++)
            if( ch[0][i] ) q[t++] = ch[0][i];
        while( h < t )
        {
            temp=q[h++];
            for(int i = 0; i < maxm; i++)
                if( !ch[temp][i] ) ch[temp][i] = ch[fail[temp]][i];
                else
                {
                    q[t++] = ch[temp][i];
                    fail[ch[temp][i]] = ch[fail[temp]][i];
                }
        }
}
int query(void)
{
    int len = strlen(s), x = 0, p = 0;
    temp = 0;
    for(int i = 0; i < len; i++)
    {
        temp = s[i]-'a';
        x = ch[x][temp];
        p = x;
        while( p && !vis[p] )
        {
            ans += flag[p];
            flag[p] = 0;
            vis[p] = 1;
            p = fail[p];
        }
    }
    return ans;
}
int main(void)
{
    scanf("%d",&T);
    while(T--)
    {
        tot = 0;
        ans = 0;
        newnode(0,-1);
        memset(vis,0,sizeof(vis));
        scanf("%d",&n);
        for(int i = 0; i < n; i++)
        {
            scanf("%s",s);
            addtrie(s);
        }
        getfail();
        scanf("%s",s);
        printf("%d\n",query());
    }
    return 0;
}

你可能感兴趣的:(AC自动机)