当前位置:编程学习 > C/C++ >>

hdu 2896 病毒侵袭 -- AC自动机

[cpp]
/*
寻找都有哪些子串
不能保证是字母或数字,所以子节点有差不多130个
*/ 
#include    
#include  
#include  
using namespace std;  
   
int biaoshi[510]; 
const int kind = 130;  
int 易做图st[10]; 
struct node{   
    node *fail;       //失败指针  
    node *next[kind];  
    int count;        //是否为该单词的最后一个节点  
    node(){           //构造函数初始化  
        fail=NULL;  
        count=0;  
        memset(next,NULL,sizeof(next));  
    }  
}*q[5000000];          //队列,方便用于bfs构造失败指针  
char keyword[510];     //输入的单词  
char str[1000010];    //模式串  
int head,tail;        //队列的头尾指针  
   
void insert(char *str,node *root,int no){  
    node *p=root;  
    int i=0,index;   
    while(str[i]){  
        index=str[i]-31;  
        if(p->next[index]==NULL) p->next[index]=new node();   
        p=p->next[index]; 
        i++; 
    }  
    p->count=no;//初始化为0,++后为1,表示是一个单词的结尾  
}  
void build_ac_automation(node *root) 

    int i; 
    root->fail=NULL;  
    q[head++]=root;  
    while(head!=tail) 
    {  
        node *temp=q[tail++];//拿到一个节点  
        node *p=NULL;  
        for(i=0;i<130;i++) 
        {  
            if(temp->next[i]!=NULL)//若其i孩子非空  
            {  
                if(temp==root) //他自己是头,其孩子的失败指针指向头  
                    temp->next[i]->fail=root;                  
                else{ //普通节点  
                    p=temp->fail; //指向自己的失败指针  
                    while(p!=NULL) 
                    {   
                        if(p->next[i]!=NULL)//失败指针有i孩子  
                        {  
                            temp->next[i]->fail=p->next[i]; //当前节点的i孩子的失败指针指向失败指针的i孩子,然后跳出  
                            break;  
                        }  
                        p=p->fail; //继续找失败指针  
                    }  
                    if(p==NULL) //若失败指针为空  
                        temp->next[i]->fail=root; //当前节点的i孩子的失败指针指向头  
                }  
                q[head++]=temp->next[i];  //进去的都是定义过失败指针的,故此过程是给其孩子定义失败指针  
            }  
        }    
    }  
}  
int query(node *root) 
{  
    int i=0,cnt=0,index,len=strlen(str);  
    node *p=root;   
    while(str[i]) 
    {   
        index=str[i]-31;  //计算孩子的位置  
        while(p->next[index]==NULL && p!=root)  
            p=p->fail; //若没有i孩子节点,通过失败指针找与这之前相同的有i孩子的节点  
        p=p->next[index]; //指向其i孩子  
        p=(p==NULL)?root:p;  
        node *temp=p;  
        while(temp!=root && temp->count) 
        {  
            if(temp->count&&!biaoshi[temp->count])//主要是改这里  
            { 
                cnt++; 
                biaoshi[temp->count]=1; 
            } 
            temp=temp->fail;  
      &nbs

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,