zoukankan      html  css  js  c++  java
  • AC自动机的简单实现

    AC自动机是著名的多模式匹配算法,给出n个单词和一篇含有m个单词的文章,找出n个单词中有多少是在文章中出现过。

    AC自动机的构造分为三步:构造trie树,构造fail指针,模式串匹配。而常用的单模式串匹配主要用kmp算法,多模式匹配与之有相似之处,因此要学习AC自动机,需要有trie树和kmp算法的知识。

    下边链接中有对AC自动机以及它的构造比较清晰的描述,笔者也是在一次面试中第一次接触到AC自动机,学习之后特来实现一下

    http://www.cppblog.com/mythit/archive/2009/04/21/80633.html

      1 HDU 2222
      2 
      3 #include <stdio.h>
      4 
      5 struct node
      6 {
      7     node * fail;
      8     node * next[26];
      9     int flag;
     10     node()
     11     {
     12         fail=NULL;
     13         for(int i=0;i<26;i++)
     14            next[i]=NULL;
     15         flag=0;
     16     }
     17 };
     18 
     19 char content[1000001];
     20 char seq[51];
     21 node * que[510000];
     22 
     23 void insert(char * str,node * root)
     24 {
     25     node * p = root;
     26     int t;
     27     while(*str)
     28     {
     29         t=*str-'a';
     30         if(p->next[t]==NULL)
     31             p->next[t]=new node();
     32         p=p->next[t];
     33         str++;
     34     }
     35     p->flag++;
     36 }
     37 
     38 void build_ac(node * root)
     39 {
     40     node *p,*q;
     41     int head,tail;
     42     head=tail=0;
     43     root->fail=NULL;
     44     que[head++]=root;
     45     while(tail<head)
     46     {
     47         p=que[tail++];
     48         for(int i=0;i<26;i++)
     49         {
     50             if(p->next[i])
     51             {
     52                 if(p==root)
     53                     p->next[i]->fail=root;
     54                 else
     55                 {
     56                     q=p->fail;
     57                     while(q!=NULL)
     58                     {
     59                         if(q->next[i])
     60                         {
     61                             p->next[i]->fail=q->next[i];
     62                             break;
     63                         }
     64                         q=q->fail;
     65                     }
     66                     if(q==NULL)
     67                         p->next[i]->fail=root;
     68                 }
     69                 que[head++]=p->next[i];
     70             }
     71         }
     72     }
     73 }
     74 
     75 int query(char * content,node * root)
     76 {
     77     node * p = root,*q,*tmp;
     78     int cnt=0;
     79     int t;
     80     while(*content)
     81     {
     82         t=*content-'a';
     83         while(p!=NULL && p->next[t]==NULL)
     84             p=p->fail;
     85         if(p==NULL)
     86             p=root;
     87         else
     88         {
     89             p=p->next[t];
     90             q=p;
     91             while(q!=root)
     92             {
     93                 if(q->flag>0)
     94                 {
     95                     cnt+=q->flag;
     96                     q->flag=-1;
     97                 }
     98                 q=q->fail;
     99             }
    100         }
    101         content++;
    102     }
    103     return cnt;
    104 }
    105 
    106 int main(int argc, char * argv[])
    107 {
    108     freopen("in","r",stdin);
    109     int t,n;
    110     scanf("%d",&t);
    111     while(t--)
    112     {
    113         scanf("%d",&n);
    114         node * root = new node();
    115         for(int i=0;i<n;i++)    //构建trie树
    116         {
    117             scanf("%s",seq);
    118             insert(seq,root);
    119         }
    120         scanf("%s",content);
    121         build_ac(root);         //构造fail指针
    122         printf("%d\n",query(content,root));  //模式串匹配
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    一个微信小程序跳转到另一个微信小程序
    微信小程序 canIUse
    微信小程序 点击事件 传递参数
    jquery 在将对象作为参数传递的时候要转换成 JSON
    微擎后台进行GET提交
    微信小程序添加底部导航栏
    jquery 中 html与text函数的区别
    C++ int与char[]的相互转换
    Qt error: LNK1158 无法运行rc.exe解决办法
    Qt error C3615: constexpr 函数 "qCountLeadingZeroBits" 不会生成常数表达式
  • 原文地址:https://www.cnblogs.com/qianye/p/3065454.html
Copyright © 2011-2022 走看看