AC自動機詳解 資料連結 http://www.cppblog.com/mythit/archive/2009/04/21/80633.html題意:給你一些單詞,,讓你統計出現文章中的單詞數....此演算法較難,必須要懂得 字典樹 , kmp 演算法,,但是還是太難,,林神也說自己忘了,要我自己看....悲催...搞了好久了....還是不懂失敗指標的用法...模板代碼: /*這是第一次寫AC自動機,字典樹明白,kmp也明白,,可就是不理解失敗指標的用法,只有先放下了,等以後思想境界高了,再來解決吧 */#include<iostream>#include<cstdio>#include<string>using namespace std;#define kind 26#define manx 500009struct node{ /// 字典樹 node *fail; /// 失敗指標 node *next[kind]; /// tire 每個節點的26個子節點(最多26個字母) int count; /// 是否為單詞的最後一個節點 node(){ /// 建構函式初始化 fail=NULL; count=0; memset(next,0,sizeof(next)); } }*q[manx]; /// 隊列,方便使用bfs構造失敗指標 char keyword[51]; ///輸入單詞 char str[manx<<1];/// 模式串 int head,tail; /// 隊列頭尾指標 void insert(char*str,node*root){ node *p=root; int i=0,index; while(str[i]){ //// 插尾法 index = str[i]-'a'; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count++;}void build_ac(node*root){ //// AC自動機演算法 root->fail=NULL; q[head++]=root; while(head!=tail){ node *temp = q[tail++]; node *p = NULL; for(int i=0;i<26;i++){ if(temp->next[i] != NULL){ if(temp==root) temp->next[i]->fail=root; else { p = temp->fail; while(p!=NULL){ if(p->next[i]!=NULL){ temp->next[i]->fail = p->next[i]; break; } p=p->fail; } if(p==NULL) temp->next[i]->fail=root; } q[head++] = temp->next[i]; } } }}int query(node *root){ //// 匹配尋找串 int i=0,cnt=0,index,len=strlen(str); node *p = root; while(str[i]){ index = str[i] - 'a'; while(p->next[index]==NULL && p!=root) p=p->fail; p = p->next[index]; p = (p==NULL)?root:p; node *temp = p; while(temp != root && temp->count != -1){ cnt += temp->count; temp -> count = -1; temp = temp->fail; } i++; } return cnt;}int main(){ int n,t; scanf("%d",&t); while(t--){ head=tail=0; node *root = new node(); scanf("%d",&n); getchar(); while(n--){ gets(keyword); insert(keyword,root); } build_ac(root); scanf("%s",str); printf("%d\n",query(root)); }}