zoukankan      html  css  js  c++  java
  • AC自动机中fail指针

    过程

    fail指针可以说是AC自动机里最难理解的东西,怎样更好的理解AC自动机的fail指针?
    先来看一幅图:

    看这幅图上的fail指针是怎么构造的.

    树上的词分别是:

    {he,hers,his,she}

    按图所示分成3层。看到第三层,是"she",其中:
    下面以"she"创建fail指针的过程为例

    • s指向root

    • h先找到s的fail指针

    发现是0号指针,不是h,然后h就不高兴了,再问问s的fail指针root:“你有没有儿子和我同名叫h的”
    root说:“有,你指向他吧”,然后h就高兴的指向了第一行的h.

    • e开始找了

    首先问他老爸h:“你的fail指针指着谁”
    h说:“图上第一行那个h啊”
    然后e就屁颠屁颠地跑去问图上第一行那个h:“你有没有名字和我一样的儿子啊”
    图上第一行那个h说:“有,他地址是xxx”
    最后e的fail指针就指向xxx地址,也就是第一行那个e了

    • 作用

    发现这样,如果一个字符串查到第三行的e以后的字符才不匹配,那说明他前面应该有个‘he’
    刚好e的失败指针指向的是第一行的‘he...’的那个e;
    这样就不用从h开始再找一遍,而是接着第一行的e继续往后找,从而节省了时间.

    转自:AC自动机 - 关于Fail指针

    (code)

    void get_fail()
    {
    	queue<int>q;
    	for(int i=0;i<26;++i){//提前处理第二层的fail指针 
    		if(ac[0].vis[i]!=0)
    		{
    			ac[ac[0].vis[i]].fail=0;//指向根节点
    			q.push(ac[0].vis[i]); 
    		}
    	} 
    	while(!q.empty())//bfs求fail指针 
            {
    		int u=q.front();
    		q.pop();
    		for(int i=0;i<26;++i)
    		{
    			if(ac[u].vis[i])//存在这个节点 
    			{
    				ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i];
    				//子节点的fail指针指向当前节点的
                                    //fail指针所指向的节点的相同子节点 
                                    q.push(ac[u].vis[i]); 
    		        }
    		        else 
                                ac[u].vis[i]=ac[ac[u].fail].vis[i]; 
    			//当前节点的这个子节点指向当
                            //前节点fail指针的这个子节点 
    		}
    	}
    }
    
  • 相关阅读:
    系统架构师基础到企业应用架构表现层
    网站性能优化之应用程序缓存中篇
    系统架构师基础到企业应用架构企业应用架构
    系统架构师基础到企业应用架构服务层
    http的请求和响应过程管道
    反射获取信息图(转)
    白话学习MVC(二)页面周期一
    Asp.Net请求原理and页面生命周期(转)
    前后台互访
    HttpApplication事件&ASP.NET页面周期
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/12493166.html
Copyright © 2011-2022 走看看