hdoj 3065 ac自动机

来源:互联网 发布:矩阵合同 编辑:程序博客网 时间:2024/05/18 18:45

算是比较裸的ac自动机


#include <iostream>#include <cstdio>#include <queue>#include <cstring>using namespace std;struct cnode{    char STR[52];    int ans;}node[1010];struct trie{    trie* next;    int isend;    int map;//往root走到当前的结点,trie树上记录的串的映射,对应node的下标    trie* child[26];    trie()    {        isend = 0;        map = 0;        memset(child,NULL,sizeof(child));        next = NULL;    }}*root,Tnum[160000];int cnt;void insert(char* str,int INDEX){    int num;    int len;    trie* ptr;    ptr = root;    int i;    len = strlen(str);    for(i = 0;i < len;i++)    {        num = str[i] - 'A';        if(ptr->child[num] == NULL)        {            ptr->child[num] = &Tnum[++cnt];//减少new的时间花费        }        ptr = ptr->child[num];    }    ptr -> isend ++;    /*    if(ptr->isend>1)      {        cout<<"yes"<<endl;        }*/    ptr->map = INDEX; }void ac_automation(){    int i;    queue<trie*> qu;    trie* current=NULL;    qu.push(root);    trie* fail = NULL;    while(!qu.empty())    {        current = qu.front();        qu.pop();        for(i = 0;i < 26;i++)        {            if(current->child[i] != NULL)            {                fail =current->next;                if(current == root)                {                    current->child[i]->next = root;                    qu.push(current->child[i]);                    continue;                }                                while(1)                {                    if(fail == NULL)                    {                        current->child[i]->next = root;                        break;                    }                    else                    {                        if(fail->child[i] != NULL)                        {                            current->child[i]->next = fail->child[i];                            break;                        }                    }                    fail = fail->next;                }                qu.push(current->child[i]);            }        }    }    }char text[2000010];int ans;void query(){    int len;    len=strlen(text);    trie* ptr;    ptr = root;    int num;    int i;    trie* temp;    for(i = 0;i<len;i++)    {        if(text[i]>='A'&&text[i]<='Z')        {            num = text[i]-'A';        }        else        {            ptr = root;            continue;        }        while(ptr->child[num] ==NULL && ptr!=root)        {            ptr = ptr->next;        }        ptr = ptr->child[num];        if(ptr == NULL)        {            ptr = root;        }        temp = ptr;        while(temp!=root &&temp->isend !=-1)        {            node[temp->map].ans+=temp->isend;            //    temp->isend = -1;            temp = temp->next;        }    }}int main(){    int n;    int i;    char str[52];    while(scanf("%d",&n)!=EOF)      {        memset(Tnum,NULL,sizeof(Tnum));        root = &Tnum[0];//减少new的时间花费        cnt=0;        for(i=0;i<n;i++)        {            scanf("%s",node[i].STR);            node[i].ans =0;            insert(node[i].STR,i);                    }        getchar();        ac_automation();    //    scanf("%s",text);        gets(text);        query();        for(i=0;i<n;i++)        {            if(node[i].ans != 0)            {                printf("%s: %d\n",node[i].STR,node[i].ans);            }        }      }        return 0;}