hdu 2896病毒侵襲 && hdu 3695 Computer Virus on Planet Pandora AC自動機

來源:互聯網
上載者:User
 /*
2896很裸的AC自動機,注意判重就ok了 */ #include<cstdio> #include<cstring> #include <iostream> #include<algorithm> #include<queue> #include<set> using namespace std; const int kind = 128;set<int> S;set<int>::iterator it; struct node{     node *fail;       //失敗指標     node *next[kind]; //Tire每個節點的26個子節點(最多26個字母)     int count,id;        //是否為該單詞的最後一個節點     node(){           //建構函式初始化         fail=NULL;         count=0;         memset(next,NULL,sizeof(next));     } };          //隊列,方便用於bfs構造失敗指標 char keyword[201];     //輸入的單詞 char str[10009];    //模式串 int head,tail;        //隊列的頭尾指標 void insert(char *str,node *root,int id){     node *p=root;     int i=0,index;     while(str[i]){         index=str[i];         if(p->next[index]==NULL) p->next[index]=new node();         p=p->next[index];         i++;     }     p->count++;     p->id=id; } void build_ac_automation(node *root){     int i;     root->fail=NULL; queue<node *> q; q.push(root);     while(!q.empty()){         node *temp=q.front();q.pop();         node *p=NULL;         for(i=0;i<128;i++){             if(temp->next[i]!=NULL){                 if(temp==root) temp->next[i]->fail=root;                 else{                     p=temp->fail;                     while(p!=NULL){                         if(p->next[i]!=NULL){                             temp->next[i]->fail=p->next[i];                             break;                         }                         p=p->fail;                     }                     if(p==NULL) temp->next[i]->fail=root;                 }q.push(temp->next[i]);             }         }     } }int n,m; int query(node *root){     int i=0,cnt=0,index,len=strlen(str);     node *p=root;     while(str[i]){         index=str[i];         while(p->next[index]==NULL && p!=root) p=p->fail;         p=p->next[index];         p=(p==NULL)?root:p;         node *temp=p;         while(temp!=root){             cnt+=temp->count;             if(temp->id>0&&temp->id<=n)             S.insert(temp->id);             temp=temp->fail;         }         i++;     }     return cnt; } int main(){ char c;     while(scanf("%d",&n)!=EOF)     {         node *root=new node();         for(int i=1;i<=n;i++)         { scanf("%s",keyword);             insert(keyword,root,i);         }         build_ac_automation(root);scanf("%d",&m);int tot=0;for(int i=1;i<=m;i++){  S.clear();         scanf("%s",str);         query(root);         if(S.size()>0)         {             printf("web %d:",i);             for(it=S.begin();it!=S.end();it++)             printf(" %d",*it);             puts("");             tot++;         }}printf("total: %d\n",tot);     }     return 0; } /* 給定匹配串和母串,統計有多少個這樣的匹配串,它自身是母串的子串或者 它翻轉後是母串的子串; 剛開始在建字典樹的時候把所以匹配串和它的子串都插入,杯具的mle 後來只插入自身,匹配的時候讓母串分別順序和逆序匹配一遍就ok了 很有啟發意義。。。 */  #include<cstdio> #include<cstring> #include <iostream>  #include<algorithm> #include<queue> using namespace std;  const int kind = 26;  struct node{       node *fail;       //失敗指標     node *next[kind]; //Tire每個節點的26個子節點(最多26個字母)     int count;        //是否為該單詞的最後一個節點     node(){           //建構函式初始化         fail=NULL;          count=0;          memset(next,NULL,sizeof(next));      }  };          //隊列,方便用於bfs構造失敗指標 char keyword[1001];     //輸入的單詞 char str[5100001];    //模式串 int head,tail;        //隊列的頭尾指標    void insert(char *str,node *root){      node *p=root;      int i=0,index;       while(str[i]){          index=str[i]-'A';          if(p->next[index]==NULL) p->next[index]=new node();           p=p->next[index];         i++;     }      p->count++;  }  void build_ac_automation(node *root){     int i;     root->fail=NULL;      //q[head++]=root;      queue<node *> q;     q.push(root);     while(!q.empty()){          node *temp=q.front();q.pop();          node *p=NULL;          for(i=0;i<26;i++){              if(temp->next[i]!=NULL){                  if(temp==root) temp->next[i]->fail=root;                                  else{                      p=temp->fail;                      while(p!=NULL){                           if(p->next[i]!=NULL){                              temp->next[i]->fail=p->next[i];                              break;                          }                          p=p->fail;                      }                      if(p==NULL) temp->next[i]->fail=root;                  }                 // q[head++]=                q.push(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]-'A';           while(p->next[index]==NULL && p!=root) p=p->fail;          p=p->next[index];          p=(p==NULL)?root:p;          node *temp=p;          while(temp!=root && temp->count!=-1){              cnt+=temp->count;              temp->count=-1;              temp=temp->fail;          }          i++;                      }         i=len-1;     while(str[i]){           index=str[i]-'A';           while(p->next[index]==NULL && p!=root) p=p->fail;          p=p->next[index];          p=(p==NULL)?root:p;          node *temp=p;          while(temp!=root && temp->count!=-1){              cnt+=temp->count;              temp->count=-1;              temp=temp->fail;          }          i--;                      }         return cnt;  }  int main(){      int n,t;      char c;     scanf("%d",&t);      while(t--){           head=tail=0;          node *root=new node();          scanf("%d",&n);          while(n--){               scanf("%s",keyword);             insert(keyword,root);         //    reverse(keyword,keyword+strlen(keyword));            // insert(keyword,root);         }          build_ac_automation(root);          int j=0;         getchar();        while(c=getchar(),c!='\n')        {            if(c=='[')            {                scanf("%d",&n);                c=getchar();                for(int i=0;i<n;i++)                str[j++]=c;                getchar();            }            else str[j++]=c;        }        str[j]='\0';         printf("%d\n",query(root));       }      return 0;  }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.