hdu 2222 Keywords Search----AC自动机

来源:互联网 发布:苏联工业知乎 编辑:程序博客网 时间:2024/06/06 00:27

Print how many keywords are contained in the description.

题意:求多少个字串   在 母串中出现过

例:

Sample Input
15shehesayshrheryasherhs
 

Sample Output
3


主要用了刘汝佳模板。。改了改,用的是UVA 1449 Dominating Patterns题的模板。。。

#include<stdio.h>

#include<string.h>#include<stdlib.h>#include<map>#include<queue>#include<string>using namespace std;#define sigma_size 26       #define maxnode 500005    //节点个数 #define MAXS 10005const int MAXN=1e6+10;char p[MAXS][55];char text[MAXN];map<string,int> ms;struct Trie//Trie模板  {  int f[maxnode];int last[maxnode];int cnt[MAXS];    //记录每个 出现的次数    int ch[maxnode][sigma_size];//maxnode表示节点个数,每个节点有26种情况,所以ch数组能表示所有情况      int val[maxnode];           //存节点的信息      int sz;                     //节点总个数      void clear(){sz=1; memset(ch[0],0,sizeof(ch[0]));memset(cnt,0,sizeof(cnt));ms.clear();}//初始化      int idx(char c){ return c - 'a'; }        void insert(char *s, int v)      {          int u=0,n=strlen(s);          for(int i=0;i<n;i++){              int c=idx(s[i]);              if(!ch[u][c]){ //节点不存在                  memset(ch[sz],0,sizeof(ch[sz]));                  val[sz]=0;                  ch[u][c]=sz++;              }              u=ch[u][c];//这样存就可以保证从每个节点,都能访问他的下一个节点了          }          val[u]=v;  ms[string(s)]=v;    }void getFail(){queue<int> q;f[0]=0;for(int c=0;c<sigma_size;c++){int u=ch[0][c];if(u){f[u]=0;  q.push(u);  last[u]=0; }}while(!q.empty()){int r=q.front(); q.pop();for(int c=0;c<sigma_size;c++){int u=ch[r][c];if(!u) {ch[r][c]=ch[f[r]][c]; continue;}q.push(u);int v=f[r];while(v && !ch[v][c] )  v=f[v];f[u]=ch[v][c];last[u]=val[f[u]]?f[u]:last[f[u]];}}}void find(char *t){int n=strlen(t);int j=0;for(int i=0;i<n;i++){int c=idx(t[i]);j=ch[j][c];if(val[j]) print(j);else if(last[j]) print(last[j]);}}void print(int j)//计算每个字符串 在 文本串中出现次数时的 print函数{if(j){cnt[val[j]]++;print(last[j]);}}};  Trie node; int main(){int t;int i,j,k;scanf("%d",&t);while(t--){int n;scanf("%d",&n);node.clear();for(i=1;i<=n;i++){scanf("%s",p[i]);node.insert(p[i],i);}node.getFail();scanf("%s",text);node.find(text);int best=-1;int sum=0;for(i=1;i<=n;i++)if(node.cnt[ms[string(p[i])]] > 0)sum++;printf("%d\n",sum);}return 0;}


原创粉丝点击