首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

hdu 2896 病毒袭击 - AC自动机

2013-04-02 
hdu 2896 病毒侵袭 -- AC自动机/*寻找都有哪些子串不能保证是字母或数字,所以子节点有差不多130个*/#inclu

hdu 2896 病毒侵袭 -- AC自动机

/*寻找都有哪些子串不能保证是字母或数字,所以子节点有差不多130个*/#include <iostream> #include<string.h>#include<stdlib.h>using namespace std;   int biaoshi[510];const int kind = 130; int dulist[10];struct node{      node *fail;       //失败指针    node *next[kind];     int count;        //是否为该单词的最后一个节点    node(){           //构造函数初始化        fail=NULL;         count=0;         memset(next,NULL,sizeof(next));     } }*q[5000000];          //队列,方便用于bfs构造失败指针char keyword[510];     //输入的单词char str[1000010];    //模式串int head,tail;        //队列的头尾指针  void insert(char *str,node *root,int no){     node *p=root;     int i=0,index;      while(str[i]){         index=str[i]-31;         if(p->next[index]==NULL) p->next[index]=new node();          p=p->next[index];        i++;    }     p->count=no;//初始化为0,++后为1,表示是一个单词的结尾} void build_ac_automation(node *root){    int i;    root->fail=NULL;     q[head++]=root;     while(head!=tail){         node *temp=q[tail++];//拿到一个节点        node *p=NULL;         for(i=0;i<130;i++){             if(temp->next[i]!=NULL)//若其i孩子非空{                 if(temp==root) //他自己是头,其孩子的失败指针指向头temp->next[i]->fail=root;                                 else{ //普通节点                    p=temp->fail; //指向自己的失败指针                    while(p!=NULL){                          if(p->next[i]!=NULL)//失败指针有i孩子{                             temp->next[i]->fail=p->next[i]; //当前节点的i孩子的失败指针指向失败指针的i孩子,然后跳出                            break;                         }                         p=p->fail; //继续找失败指针                    }                     if(p==NULL) //若失败指针为空temp->next[i]->fail=root; //当前节点的i孩子的失败指针指向头                }                 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]-31;  //计算孩子的位置        while(p->next[index]==NULL && p!=root) p=p->fail; //若没有i孩子节点,通过失败指针找与这之前相同的有i孩子的节点        p=p->next[index]; //指向其i孩子        p=(p==NULL)?root:p;         node *temp=p;         while(temp!=root && temp->count){ if(temp->count&&!biaoshi[temp->count])//主要是改这里{cnt++;biaoshi[temp->count]=1;}            temp=temp->fail;         }         i++;                     }        return cnt; } int cmp(const void *a,const void *b){int *c=(int*)a,*d=(int*)b;return *c-*d;}void print(int ji,int na,int n){printf("web %d:",na);for(int i=1;i<=n;++i){if(biaoshi[i]){printf(" %d",i);}}printf("\n");}int main(){     int n,t,i,j=0;     while(scanf("%d",&n)!=EOF){          head=tail=0;         node *root=new node();               getchar();         for(i=1;i<=n;i++){            gets(keyword);             insert(keyword,root,i);         }         build_ac_automation(root); scanf("%d",&t);for(i=1;i<=t;++i){memset(biaoshi,0,sizeof(biaoshi));scanf("%s",str); int ge=query(root);if(ge){print(ge,i,n);j++;}}printf("total: %d\n",j);    }     return 0; }

热点排行