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指針的這個子節點 
		}
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM