hdu 2896 AC自动机

 题目说是可见字符,ASCII码中可见字符的前面一位是' '空格,next数组大小100就可以了,字符转化成数字需要减去' '这个字符

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e7 + 5;
const int nsize = 26;

struct node
{
    node *next[nsize];
    node *fail;
    int sum;
};

int cnt;
node *root;

//构造字典树
void Insert(char *s)
{
    node *newnode,*p;
    p = root;
    for(int i = 0; s[i]; i++)
    {
        int x = s[i] - 'a';
        if(p->next[x] == NULL)
        {
            newnode=(struct node *)malloc(sizeof(struct node));
            for(int j=0; j<nsize; j++) newnode->next[j] = 0;
            newnode->sum = 0;
            newnode->fail = 0;
            p->next[x]=newnode;
        }
        p = p->next[x];
    }
    p->sum++;
}

//构造失败指针
void build_fail() {
    queue<node*> Q;
    Q.push(root);
    while (!Q.empty()) {
        node *p = Q.front();
        Q.pop();
        for(int i = 0; i < nsize; i++) {
            if (p->next[i]) {
                if (p == root)
                    p->next[i]->fail = p;
                else {
                    node *tmp = p->fail;
                    while (tmp) {
                        if (tmp->next[i]) {
                            p->next[i]->fail = tmp->next[i];
                            break;
                        }
                        else tmp = tmp->fail;
                    }
                    if (!tmp) p->next[i]->fail = root;
                }
                Q.push(p->next[i]);
            }
        }
    }
    return ;
}

//匹配
void ac_automation(char *ch)
{
    node *p = root;
    int len = strlen(ch);
    for(int i = 0; i < len; i++)
    {
        int x = ch[i] - 'a';
        while(!p->next[x] && p != root)
        {
            p = p->fail;
            if(p->sum > 0)
            {
                cnt += p->sum;  //不想改变sun值就用vis数组标记
                p->sum = -1;
            }
        }
        p = p->next[x];
        if(!p) p = root;
        node *temp = p;
        while(temp != root)
        {
            if(temp->sum > 0)
            {
                cnt += temp->sum;
                temp->sum = -1;
            }
            else break;
            temp = temp->fail;
        }
    }
}

char key[70],pattern[maxn];

int main()
{
//    freopen("Input.txt","r",stdin);
    int T,N;
    scanf("%d",&T);
    while(T--)
    {
        root=(struct node *)malloc(sizeof(struct node));
        for(int j=0; j<nsize; j++) root->next[j] = 0;
        root->fail = 0;
        root->sum = 0;
        scanf("%d",&N);
        getchar();
        for(int i = 1; i <= N; i++)
        {
            gets(key);
            Insert(key);
        }
        gets(pattern);
        cnt = 0;
        build_fail();
        ac_automation(pattern);
        printf("%d\n",cnt);
    }
    return 0;
}

 

posted @ 2017-07-26 17:39  Pacify  阅读(271)  评论(0编辑  收藏  举报