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

posted on 2014-07-07 10:46  XtestW  阅读(164)  评论(0编辑  收藏  举报

导航