hdu 3065 AC自动机模版题
题意:输出每个模式串出现的次数,查询的时候呢使用一个数组进行记录就好。同上题一样的关键点,其他没什么难度了。
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxw = 1000 * 50 + 10; const int sigma_size = 128; const int maxl = 2000000 + 10; char str[1010][100]; struct Trie{ int next[maxw][sigma_size],fail[maxw],end[maxw]; int root,L; int newnode(){ for(int i=0;i<sigma_size;i++) next[L][i]=-1; end[L++]=-1; return L-1; } void init(){ L=0; root=newnode(); } void insert(const char *s,int id){ int now=root,len=strlen(s); for(int i=0;i<len;i++){ if(next[now][s[i]]==-1) next[now][s[i]]=newnode(); now=next[now][s[i]]; } end[now]=id; } void build(){ queue<int>Q; fail[root]=root; for(int i=0;i<sigma_size;i++) if(next[root][i]==-1) next[root][i]=root; else{ fail[next[root][i]]=root; Q.push(next[root][i]); } while(!Q.empty()){ int now=Q.front(); Q.pop(); for(int i=0;i<sigma_size;i++) if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else{ fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } int num[1000 + 10]; void query(const char *buf,int n){ memset(num,0,sizeof(num)); int now=root,len=strlen(buf); for(int i=0;i<len;i++){ now=next[now][buf[i]]; int tmp=now; while(tmp!=root){ if(end[tmp]!=-1) num[end[tmp]]++; tmp=fail[tmp]; } } for(int i=0;i<n;i++) if(num[i]) printf("%s: %d\n",str[i],num[i]); } }; char buf[maxl]; Trie ac; int main() { int n; while(~scanf("%d",&n)){ ac.init(); for(int i=1;i<=n;i++){ scanf("%s",str[i]); ac.insert(str[i],i); } ac.build(); scanf("%s",buf); ac.query(buf,n); } return 0; }
补充:软件开发 , C++ ,