POJ 4052-Hrinity(KMP算法+AC自动机)

来源:互联网 发布:列主元三角分解法C语言 编辑:程序博客网 时间:2024/05/29 17:56

题目大意:给出一系列模式串,可能是以压缩形式给出的,并给出文本串,求问模式串总共出现了多少次,如果同一个模式串出现多次,只算一次,如果模式串A和B出现了,模式串B是A的子串,那么B不算。


首先对字符串解压,然后对解压之后的模式串存入AC自动机中,接着算出哪些匹配,对于那些匹配的,我是KMP算法判断是否有子串的关系。


#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXNODE 1010*2500+10#define SIZE 26char a[5100010];int c[2510];char e[2510][1050];int ch[MAXNODE][SIZE];int q[MAXNODE];int last[MAXNODE];int val[MAXNODE];int next[MAXNODE];int wor[MAXNODE];char T[5100010];char datin[1050];int KMP_next[1050];int m,siz,front,rear,top;void decoding(char*b);void ACauto_init(void);void trie_insert(void);void ACauto_next(void);void ACauto_matcher(void);void ACauto_printf(int j);int KMP_matcher(char*P,char*T);void KMP_tonext(char*P);int main(void){int i,j,n,pi,qi,sum,OK;scanf("%d",&pi);for(qi=0;qi<pi;qi++){scanf("%d",&n);ACauto_init();for(i=1;i<=n;i++){scanf("%s",a+1);c[i]=0;decoding(datin);strcpy(e[i]+1,datin+1);top=i;trie_insert();}scanf("%s",a+1);decoding(T);ACauto_next();ACauto_matcher();for(i=1;i<n;i++){for(j=i+1;j<=n;j++){if((c[i]!=0)&&(c[j]!=0)&&(strlen(e[i]+1)>strlen(e[j]+1))){m=strlen(e[j]+1);KMP_tonext(e[j]);OK=KMP_matcher(e[j],e[i]);if(OK==0){c[j]=0;}}else if((c[i]!=0)&&(c[j]!=0)&&(strlen(e[i]+1)<strlen(e[j]+1))){m=strlen(e[i]+1);KMP_tonext(e[i]);OK=KMP_matcher(e[i],e[j]);if(OK==0){c[i]=0;}}}}sum=0;for(i=1;i<=n;i++){sum=sum+c[i];}printf("%d\n",sum);}return 0;}void decoding(char*b){int j,u,lo,top,sump;lo=strlen(a+1);top=0;j=1;while(j<=lo){if((a[j]>='A')&&(a[j]<='Z')){top++;b[top]=a[j];j++;}else if(a[j]=='['){j++;sump=0;while((a[j]>='0')&&(a[j]<='9')){sump=sump*10+a[j]-'0';j++;}u=0;while(u<sump){top++;b[top]=a[j];u++;}j++;}else{j++;}}top++;b[top]=0;}void trie_insert(void){int i,j,u,lo,now;now=0;lo=strlen(datin+1);for(i=1;i<=lo;i++){j=datin[i]-'A';if(ch[now][j]==0){siz++;for(u=0;u<SIZE;u++){ch[siz][u]=0;}val[siz]=0;ch[now][j]=siz;}now=ch[now][j];}val[now]=top;}void ACauto_next(void){int j,u,v,now;next[0]=0;front=rear=0;for(u=0;u<SIZE;u++){j=ch[0][u];if(j!=0){next[j]=0;rear++;q[rear]=j;last[j]=0;}}while(front<rear){front++;now=q[front];for(u=0;u<SIZE;u++){j=ch[now][u];if(j!=0){rear++;q[rear]=j;v=next[now];while((v!=0)&&(ch[v][u]==0)){v=next[v];}next[j]=ch[v][u];last[j]=(val[next[j]]!=0)?next[j]:last[next[j]];}else{ch[now][u]=ch[next[now]][u];}}}}void ACauto_matcher(void){int i,j,u,lo;lo=strlen(T+1);u=0;for(i=1;i<=lo;i++){j=T[i]-'A';u=ch[u][j];if(val[u]!=0){ACauto_printf(u);}else if(last[u]!=0){ACauto_printf(last[u]);}}}void ACauto_printf(int j){if(j!=0){c[val[j]]=1;ACauto_printf(last[j]);}}void ACauto_init(void){int u;for(u=0;u<SIZE;u++){ch[0][u]=0;}val[0]=0;siz=0;}int KMP_matcher(char*P,char*T){int i,u,lo;lo=strlen(T+1);u=0;for(i=1;i<=lo;i++){while((u>0)&&(T[i]!=P[u+1])){u=KMP_next[u];}if(T[i]==P[u+1]){u++;}if(u==m){return 0;u=KMP_next[u];}}return 1;}void KMP_tonext(char*P){int i,u,lo;lo=strlen(P+1);KMP_next[1]=0;for(i=2;i<=lo;i++){u=KMP_next[i-1];while((u>0)&&(P[u+1]!=P[i])){u=KMP_next[u];}if(P[u+1]==P[i]){u++;}KMP_next[i]=u;}}


0 0