您的位置:首页 > 编程语言

HDU_2222 大部分是别人的,有的地方稍有改动,代码有不完善的地方!

2014-02-14 11:49 483 查看
大部分是别人的,有的地方稍有改动
[cpp]
 view
plaincopy

#include<iostream>  

#include<cstdio>  

#include<cstring>  

#include<string>  

using namespace std;  

#define N 500010  

char str[1000010], keyword[51];  

int head, tail;  

  

struct node  

{  

    node *fail;  

    node *next[26];  

    int count;  

    node() //初始化,(类似于构造函数)

    {  

        fail = NULL;  

        count = 0;  

        for(int i = 0; i < 26; ++i)  

            next[i] = NULL;  

    }  

}*q
;  

node *root;  

void trie(char *keyword) //建立Trie,每次只能建立一个keyword。  

{  

    int temp, length;  

    node *p = root;  

    length = strlen(keyword);  

    for(int i = 0; i < length; ++i)  

    {  

        temp = keyword[i] - 'a';  

        if(p->next[temp] == NULL)  

            p->next[temp] = new node();
 

        p = p->next[temp];  

    }  

    p->count++;  

}   

void build_ac() //初始化fail指针,BFS  

{  

    q[tail++] = root;  

    while(head != tail)  

    {  

        node *p = q[head++]; //弹出队头  

        node *temp = NULL;  

        for(int i = 0; i < 26; ++i)  

        {  

            if(p->next[i] != NULL)  

            {  

                if(p == root) //第一个元素fail必指向根  

                    p->next[i]->fail = root;  

                else  

                {  

                    temp = p->fail; //失败指针  

                    while(temp != NULL) //2种情况结束:匹配为空or找到匹配  

                    {  

                        if(temp->next[i] != NULL) //找到匹配  

                        {  

                            p->next[i]->fail = temp->next[i];  

                            break;  

                        }  

                        temp = temp->fail;  

                    }  

                    if(temp == NULL) //为空则从头匹配  

                        p->next[i]->fail = root;  

                }  

                q[tail++] = p->next[i]; //入队  

            }  

        }  

    }  

}   

int query() //扫描  

{  

    int index, length, result;  

    node *p = root; //Tire入口  

    result = 0;  

    len = strlen(str);  

    for(int i = 0; i < length; ++i)  

    {  

        index = str[i] - 'a';  

        while(p->next[index] == NULL && p != root) //跳转失败指针  

            p = p->fail;  

        p = p->next[index];  

        if(p == NULL)  

            p = root;  

        node *temp = p; //p不动,temp计算后缀串  

        while(temp != root && temp->count != -1)  

        {  

            result += temp->count;  

            temp->count = -1;  

            temp = temp->fail;  

        }  

    }  

    return result;  

}    

int main()  

{  

    int ncase, number;  

    scanf("%d", &ncase);  

    while(ncase--)  

    {  

        head= tail = 0;  

        root = new node();  

        scanf("%d", &number);  

        getchar();  

        for(int i = 0; i < number; ++i)  

        {  

            gets(keyword);  

            trie(keyword);  

        }  

        build_ac();  

        scanf("%s", str);  

        printf("%d\n", query());  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AC自动机