HDU-2222 Keywords Search 字符串問題 AC自動機
阿新 • • 發佈:2018-08-02
tex cnblogs key .html 開始 mit name 都是 root
題目鏈接:https://cn.vjudge.net/problem/HDU-2222
題意
給一些關鍵詞,和一個待查詢的字符串
問這個字符串裏包含多少種關鍵詞
思路
AC自動機模版題咯
註意一般情況不需要修改build方法,就像kmp裏的getfail一樣
一般的題目就是改改insert,query
一開始寫的模版總是有問題,懶得改了
直接找的kuangbin的模版【原創】AC自動機小結
註意數組和指針的效率差不了多少,此題同一個算法的指針形式(296ms)比數組(187ms)慢110ms
說實在的,數組寫法就是優雅。
網上那些指針的看著就難受,明明是好好的邏輯,變量名都是pqrvtxy,搞的跟被混淆了一樣。
改了兩套沒一個舒服的,真難受。
提交過程
AC |
代碼
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int ACSize=500000+20; const int maxitem=26, maxn=1e4+20, maxword=50+20, maxl=1e6+20; char word[maxword], line[maxl]; struct Trie{ int next[ACSize][26], fail[ACSize], cnt[ACSize]; int root, total; int newnode(void){ for(int pos=0; pos<maxitem; pos++) next[total][pos]=-1; cnt[total]=0; return total++; } void init(){ total=0; root=newnode(); } void insert(char buf[]){ int now=root; for(int i=0; buf[i]; i++){ int pos=buf[i]-‘a‘; if(next[now][pos]==-1) next[now][pos]=newnode(); now=next[now][pos]; } cnt[now]++; } void build(void){ queue<int> que; fail[root]=root; for(int i=0; i<maxitem; i++) if(next[root][i]==-1) next[root][i]=root; else{ fail[next[root][i]]=root; que.push(next[root][i]); } while(!que.empty()){ int now=que.front(); que.pop(); for(int pos=0; pos<maxitem; pos++) if(next[now][pos]==-1) next[now][pos]=next[fail[now]][pos]; else{ fail[next[now][pos]]=next[fail[now]][pos]; que.push(next[now][pos]); } } } int query(char buf[]){ int now=root, res=0; for(int i=0; buf[i]; i++){ int pos=buf[i]-‘a‘; now=next[now][pos]; for (int tmp=now; tmp!=root && cnt[tmp]!=-1; tmp=fail[tmp]){ res+=cnt[tmp]; cnt[tmp]=-1; // 註意此處,找到了就不要找第二次了,直接刪除即可 } }return res; } void debug(void){ for(int i=0; i<total; i++){ printf("id=%3d, fail=%3d, end=%3d [", i, fail[i], cnt[i]); for(int j=0; j<maxitem; j++) printf("%2d", next[i][j]); printf("]\n"); } } }AC; int main(void){ int T, n; scanf("%d", &T); while (T--){ AC.init(); scanf("%d", &n); for (int i=0; i<n; i++){ scanf("%s", word); AC.insert(word); }AC.build(); scanf("%s", line); printf("%d\n", AC.query(line)); } return 0; }
Time | Memory | Length | Lang | Submitted |
---|---|---|---|---|
187ms | 27744kB | 2369 | G++ | 2018-08-02 16:16:21 |
HDU-2222 Keywords Search 字符串問題 AC自動機