zoukankan      html  css  js  c++  java
  • hdu 2222(AC自动机第一题)

    题意:首先输入n个单词,然后输入一个字符串,题目要求的事在传中可以找到几个开始输入的单词。

    分析:这是我做的第一个AC自动机模板题,对于刚开始学习AC自动机的人我推荐两个资料:第一个:file:///C:/Users/Administrator/AppData/Local/Temp/360zip$Temp/360$0/AC自动机算法详解%20-%20极限定律%20-%20C++博客.mht

    第二个资料:这个我觉得也挺好的,http://www.cnblogs.com/zhuangli/archive/2008/08/13/1267249.html

    看完这两个资料之后这道题就不是问题了!

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    using namespace std;
    struct node{
        int count;
        struct node *fail;
        struct node *next[26];
        node()
        {
            fail=NULL;
            memset(next,NULL,sizeof(next));
            count=0;
        }
    }*queue[500005];
    struct node *root;
    char keyword[55],str[1000005];
    void build(char *str)//建立字典树
    {
         struct node *p=p=root;
         int index;
         for(;*str!='\0';str++)
         {
             index=*str-'a';
             if(p->next[index]==NULL)
                 p->next[index]=new node;
             p=p->next[index];
         }
         p->count++;
    }
    void AC_tree()//构造失败指针
    {
         int f,r,i;
         struct node *p,*temp;
         root->fail=NULL;
         f=0;r=0;
         queue[r++]=root;
         while(f!=r)
         {
            p=queue[f++];
            for(i=0;i<26;i++)
            {
               if(p->next[i]!=NULL)
               {
                   temp=p->fail;
                   while(temp!=NULL)
                   {
                      if(temp->next[i]!=NULL)
                      {
                          p->next[i]->fail=temp->next[i];
                          break;
                      }
                      temp=temp->fail;
                   }
                   if(temp==NULL)
                       p->next[i]->fail=root;
                   queue[r++]=p->next[i];
               }
            }
         }
    }
    int find(char *str)//单词查找
    {
         int index;
         int sum=0;
         struct node *p,*temp;
         p=root;
         for(;*str!='\0';str++)
         {
             index=*str-'a';
             while(p->next[index]==NULL&&p!=root)
                 p=p->fail;
             p=p->next[index];
             if(p==NULL)
                 p=root;
             temp=p;
             while(temp!=root&&temp->count!=-1)
             {
                sum=sum+temp->count;
                temp->count=-1;
                temp=temp->fail;
             }
         }
         return sum;
    }
    void del(struct node *root)
    {
       int i;
       for(i=0;i<26;i++)
       {
           if(root->next[i]!=NULL)
               del(root->next[i]);
       }
       delete(root);
    }
    int main()
    {
        int T,n;
        while(scanf("%d",&T)!=EOF)
        {
            while(T--)
            {
                root=new node;
                scanf("%d",&n);
                getchar();
                while(n--)
                {
                    scanf("%s",keyword);
                    build(keyword);
                }
                AC_tree();
                scanf("%s",str);
                printf("%d\n",find(str));
                del(root);
            }
        }
        return 0;
    }

     用静态数组模拟:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    struct node{
        int next[26];
        int fail;
        int count;
        void init()
        {
            memset(next,0,sizeof(next));
            fail=0;
            count=0;
        }
    };
    struct node a[500005];
    int n,tot;
    char keyword[55];
    char S[1000005];

    void chushihua()
    {
        tot=0;
        a[0].init();
    }

    void insert(char *str)
    {
         int index,p;
         p=0;
         for(;*str!='\0';str++)
         {
             index=*str-'a';
             if(a[p].next[index]==0)
             {
                 a[++tot].init();
                 a[p].next[index]=tot;
             }
             p=a[p].next[index];
         }
         a[p].count++;
    }

    void build_fail()
    {
         int i,p,son,cur;
         queue<int>Q;
         Q.push(0);
         while(!Q.empty())
         {
             p=Q.front();
             Q.pop();
             for(i=0;i<26;i++)
             {
                   if(a[p].next[i]!=0)
                   {
                        son=a[p].next[i];
                        cur=a[p].fail;
                        if(p==0)
                           a[son].fail=0;
                        else
                        {
                           while(cur!=0&&a[cur].next[i]==0)
                               cur=a[cur].fail;
                           a[son].fail=a[cur].next[i];
                        }
                        Q.push(son);
                   }
             }
         }
    }

    int solve()
    {
        int i,index,p=0,temp,res;
        res=0;
        for(i=0;S[i]!='\0';i++)
        {
             index=S[i]-'a';
             while(p!=0&&a[p].next[index]==0)
                p=a[p].fail;
             if(a[p].next[index]!=0)
                 p=a[p].next[index];
             temp=p;
             while(temp&&a[temp].count!=-1)
             {
                 res=res+a[temp].count;
                 a[temp].count=-1;
                 temp=a[temp].fail;
             }
        }
        return res;
    }
    int main()
    {
        int T;
        while(scanf("%d",&T)!=EOF)
        {
            while(T--)
            {
                chushihua();
                  scanf("%d",&n);
                getchar();
                while(n--)
                {
                   scanf("%s",keyword);
                   insert(keyword);
                }
                build_fail();
                scanf("%s",S);
                printf("%d\n",solve());
            }
        }
        return 0;
    }

  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/jiangjing/p/3036701.html
Copyright © 2011-2022 走看看