ac自动机模板(hdu2222)
生活随笔
收集整理的這篇文章主要介紹了
ac自动机模板(hdu2222)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- 具體代碼;??
- #include?<stdio.h>??
- #include?<stdlib.h>??
- #include?<string.h>??
- struct?Node??
- {??
- ????int?cnt;//是否為該單詞的最后一個結點???
- ????Node?*fail;//失敗指針???
- ????Node?*next[26];//Trie中每個結點的各個節點???
- }*queue[500005];//隊列,方便用BFS構造失敗指針???
- char?s[1000005];//主字符串???
- char?keyword[55];//需要查找的單詞???
- Node?*root;//頭結點???
- void?Init(Node?*root)//每個結點的初始化???
- {??
- ????root->cnt=0;??
- ????root->fail=NULL;??
- ????for(int?i=0;i<26;i++)??
- ????????root->next[i]=NULL;??
- }??
- void?Build_trie(char?*keyword)//構建Trie樹???
- {??
- ????Node?*p,*q;??
- ????int?i,v;??
- ????int?len=strlen(keyword);??
- ????for(i=0,p=root;i<len;i++)??
- ????{??
- ????????v=keyword[i]-'a';??
- ????????if(p->next[v]==NULL)??
- ????????{??
- ????????????q=(struct?Node?*)malloc(sizeof(Node));??
- ????????????Init(q);??
- ????????????p->next[v]=q;//結點鏈接???
- ????????}??
- ????????p=p->next[v];//指針移動到下一個結點???
- ????}??
- ????p->cnt++;//單詞最后一個結點cnt++,代表一個單詞???
- }??
- void?Build_AC_automation(Node?*root)??
- {??
- ????int?head=0,tail=0;//隊列頭、尾指針???
- ????queue[head++]=root;//先將root入隊???
- ????while(head!=tail)??
- ????{??
- ????????Node?*p=NULL;??
- ????????Node?*temp=queue[tail++];//彈出隊頭結點???
- ????????for(int?i=0;i<26;i++)??
- ????????{??
- ????????????if(temp->next[i]!=NULL)//找到實際存在的字符結點???
- ????????????{?//temp->next[i]?為該結點,temp為其父結點???
- ????????????????if(temp==root)//若是第一層中的字符結點,則把該結點的失敗指針指向root???
- ????????????????????temp->next[i]->fail=root;??
- ????????????????else??
- ????????????????{??
- ????????????????????//依次回溯該節點的父節點的失敗指針直到某節點的next[i]與該節點相同,??
- ????????????????????//則把該節點的失敗指針指向該next[i]節點;???
- ????????????????????//若回溯到?root?都沒有找到,則該節點的失敗指針指向?root??
- ????????????????????p=temp->fail;//將該結點的父結點的失敗指針給p???
- ????????????????????while(p!=NULL)??
- ????????????????????{??
- ????????????????????????if(p->next[i]!=NULL)??
- ????????????????????????{??
- ????????????????????????????temp->next[i]->fail=p->next[i];??
- ????????????????????????????break;??
- ????????????????????????}??
- ????????????????????????p=p->fail;??
- ????????????????????}??
- ????????????????????//讓該結點的失敗指針也指向root???
- ????????????????????if(p==NULL)??
- ????????????????????????temp->next[i]->fail=root;??
- ????????????????}??
- ????????????????queue[head++]=temp->next[i];//每處理一個結點,都讓該結點的所有孩子依次入隊???
- ????????????}??
- ????????}??
- ????}??
- }??
- int?query(Node?*root)??
- {?//i為主串指針,p為模式串指針???
- ????int?i,v,count=0;??
- ????Node?*p=root;??
- ????int?len=strlen(s);??
- ????for(i=0;i<len;i++)??
- ????{??
- ????????v=s[i]-'a';??
- ????????//由失敗指針回溯查找,判斷s[i]是否存在于Trie樹中???
- ????????while(p->next[v]==NULL?&&?p!=root)??
- ????????????p=p->fail;??
- ????????p=p->next[v];//找到后p指針指向該結點???
- ????????if(p==NULL)//若指針返回為空,則沒有找到與之匹配的字符???
- ????????????p=root;??
- ????????Node?*temp=p;//匹配該結點后,沿其失敗指針回溯,判斷其它結點是否匹配???
- ????????while(temp!=root)//匹配結束控制???
- ????????{??
- ????????????if(temp->cnt>=0)//判斷該結點是否被訪問???
- ????????????{??
- ????????????????count+=temp->cnt;//由于cnt初始化為?0,所以只有cnt>0時才統計了單詞的個數???
- ????????????????temp->cnt=-1;//標記已訪問過???
- ????????????}??
- ????????????else//結點已訪問,退出循環???
- ????????????????break;??
- ????????????temp=temp->fail;//回溯?失敗指針?繼續尋找下一個滿足條件的結點???
- ????????}??
- ????}??
- ????return?count;??
- }??
- int?main()??
- {??
- ????int?T,n;??
- ????scanf("%d",&T);??
- ????while(T--)??
- ????{??
- ????????root=(struct?Node?*)malloc(sizeof(Node));??
- ????????Init(root);??
- ????????scanf("%d",&n);??
- ????????for(int?i=0;i<n;i++)??
- ????????{??
- ????????????scanf("\n%s",keyword);??
- ????????????Build_trie(keyword);??
- ????????}??
- ????????Build_AC_automation(root);??
- ????????scanf("\n%s",s);??
- ????????printf("%d\n",query(root));??
- ????}??
- ????return?0;??
- }??
總結
以上是生活随笔為你收集整理的ac自动机模板(hdu2222)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多囊卵巢做试管怎么样
- 下一篇: EK算法网络流模板hdu1532