hdu2222 AC自动机

<span style="font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">在trie树的基础上增加fail指针。</span>插入函数是忘记更新节点,找了好久好久!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>

using namespace std;

#define MAXN 26
#define MAXX 1000005
int sum ;
char arr[MAXX];
struct node
{
    int num;
    char str;
    node *fail;
    node *next[MAXN];
    node()
    {
        num = 0;
        fail = NULL;
        for(int i = 0 ; i < MAXN ; i ++ )
            next[i] = NULL ;
    }
};

void Insert(node *root,char a[])
{
    node *current , *newnode;
    int len = strlen(a);
    current = root ;
    for(int i = 0 ; i < len ; i ++ )
    {
        int m = a[i] - 'a';
        if(current -> next[m] != NULL)
        {
            current = current -> next[m];<span style="white-space:pre">		</span>//被坑,忘记更新当前结点
            if(i == len - 1) (current -> num) ++ ;
        }
        else
        {
            newnode = new node();
            newnode -> str = a[i];
            current -> next[m] = newnode;
            current = newnode;
            if(i == len - 1) (current -> num) ++;
        }
    }
}
/*
void show(node *root)
{
    queue <node*>Q;
    for(int i = 0 ; i < MAXN ; i ++ )
    {
        if(root -> next[i] != NULL) Q.push(root -> next[i]);
    }
    while(!Q.empty())
    {
        node *newnode;
        newnode = Q.front();
        Q.pop();
        cout << newnode -> str << endl ;
        for(int i = 0 ; i < MAXN ; i ++ )
        {
            if(newnode -> next[i] != NULL) Q.push(newnode -> next[i]);
        }
    }
}
*/
void BuildFail(node *root)
{

    queue <node*>Q;
    root -> fail = root;
    for(int i = 0 ; i < MAXN ; i ++ )
    {
        if(root -> next[i] == NULL)
        {
             root -> next[i]  = root ;
        }
        else
        {
            root -> next[i] -> fail = root ;
            Q.push(root -> next[i]);
        }

    }
    while(!Q.empty())
    {
        node *current ;
        current = Q.front();
        Q.pop();
        for(int i = 0 ; i < 26 ; i ++ )
        {
            if(current -> next[i] == NULL)
                current -> next[i]  = current -> fail -> next[i];<span style="white-space:pre">		</span>//建立fail指针关键点1
            else
            {
           //     cout << current -> next[i] ->str << endl ;
                current -> next[i] -> fail = current -> fail -> next[i];<span style="white-space:pre">		</span>//简历里fail指针关键点2
                Q.push(current -> next[i]);
            }
        }
    }
}

void Query(node *root,char a[])
{
    node *current , *newnode;
    int len = strlen(a);
    current = root;
    for(int i = 0 ; i < len ; i ++ )
    {
        int m = a[i] - 'a';
        while(current -> next[m] == NULL && current != root) current = current -> fail;<span style="white-space:pre">		</span>//匹配注意点1
        current = current -> next[m];
     //   cout << current -> str << endl;
        newnode = current ;
        while(newnode != root)<span style="white-space:pre">			</span>//匹配注意点2
        {
          //  cout << newnode -> str << endl ;
          //  cout << newnode -> num << endl ;
            sum += newnode -> num ;
            newnode ->  num = 0;
            newnode = newnode -> fail ;
        }
    }
}

int main()
{
    int t;
    scanf("%d" , &t) ;
    while(t -- )
    {
        node *root = new node();

        int n;
        scanf("%d" , &n) ;
        getchar();
        char a[55];
        for(int i = 0 ; i < n ; i ++ )
        {
            gets(a);
            Insert(root,a);
        }
      //  show(root);
        sum = 0;
        BuildFail(root);
        gets(arr);

        Query(root,arr);
        cout << sum << endl ;
    }
}

你可能感兴趣的:(hdu2222 AC自动机)