zoukankan      html  css  js  c++  java
  • AC 自动机

    AC 自动机主要有3个步骤:

    1.构造trie树

    2.在trie树的基础上,添加失败指针,其添加方法就是一句话:由父亲节点开始,沿着失败指针向上找,一直找到一个节点p的next[i]不为空或者到根节点,把当前节点的next[i]的失败指针指向p的next[i]

    3.进行模式串的匹配

    hdu 2222 代码,可兼作模板:

    /*
     * Author:  xtestw
     * Created Time:  2014/7/7 8:54:30
     * File Name: 2222.cpp
     */
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <set>
    #include <time.h>
    using namespace std;
    const int maxint = -1u>>1;
    string image;
    string strs[10010];
    struct Node{
        Node *next[26];
        Node *fail;
        int count;
        Node(){
            fail=NULL;
            memset(next,NULL,sizeof(next));
            count=0;
        }
    }*q[500010];
    Node* root;
    
    
    void insert(string 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 buildfail(Node *root){
        int i;
        root->fail=NULL;
        int head,tail;
        head=tail=0;
        q[head++]=root;
        while (head!=tail)
        {
            Node *tmp=q[tail++];
            Node *p=NULL;
            for(int i=0;i<26;i++)
            {
                if (tmp->next[i]!=NULL)
                {
                    if (tmp==root) tmp->next[i]->fail=root;
                    else{
                        p=tmp->fail;
                        while (p!=NULL)
                        {
                            if (p->next[i]!=NULL)
                            {
                                tmp->next[i]->fail=p->next[i];
                                break;
                            }
                            p=p->fail;
                        }
                        if (p==NULL) tmp->next[i]->fail=root;
                    }
                    q[head++]=tmp->next[i];
                }
            }
        }
    }
    
    int query(Node *root)
    {
        int i=0,cnt=0,index,len=image.size();
        Node *p=root;
        while (image[i])
        {
            index=image[i]-'a';
            while (p->next[index]==NULL && p!=root) p=p->fail;
            p=p->next[index];
            p=(p==NULL)?root:p;
            Node *tmp=p;
            while (tmp!=root && tmp->count!=-1){
                cnt+=tmp->count;
                tmp->count=-1;
                tmp=tmp->fail;
            }
            i++;
        }
        return cnt;
    }
    int main() {
    #ifndef ONLINE_JUDGE
       freopen("f:/in.txt","r",stdin);
    #endif
      ios::sync_with_stdio(0); 
        int T;
        cin>>T;
        while (T--){
            root=new Node();
            int n;
            cin>>n;
            for(int i=0;i<n;i++) cin>>strs[i];
            cin>>image;
            for(int i=0;i<n;i++)
            {
                insert(strs[i],root);
            }
                buildfail(root);
            cout<<query(root)<<endl;
        }
           return 0;
    }

    详细的参看:http://www.cppblog.com/mythit/archive/2009/04/21/80633.html

  • 相关阅读:
    Springboot 基于的SAP项目环境配置
    Impala 技术点梳理
    Elasticsearch 使用技巧笔记
    ELK 6.x 部署
    eclipse安装lombok
    IIS服务器管理学习
    Springboot依赖注入笔记
    Eclipse解决乱码问题
    Springboot依赖注入 Service类中使用静态变量
    javascript 操作符类型隐性转换
  • 原文地址:https://www.cnblogs.com/xtestw/p/3829223.html
Copyright © 2011-2022 走看看