AC自動機詳解

2021-09-27 13:32:42 字數 1615 閱讀 4286

首先,看清楚了,這是ac自動機不是自動ac機

引用ac自動機模板題上的一句話:

ovo在學習ac自動機之前,應該先掌握一下兩個前置技能:

ac自動機,通俗地講,就是在trie上跑kmp。ac自動機利用trie的性質和kmp的思想,可以實現字串的多模匹配。kmp是單模匹配,而它與ac自動機最大的區別就在fail指標的求法,其餘思想基本相同。

所謂多模匹配,即給出若干個模式串和乙個文字串,需要查詢這些模式串在文字串**現的情況。

ac自動機的操作分為三步:

一、建樹

既然是要利用trie,自然要先建立一棵trie了。本文以she,he,say,her,shr五個字串為例建立一棵trie:

其中,root為根節點,綠色節點表示該節點為某個單詞的結尾,也就是結尾標記。

ac自動機的建樹方法與trie完全相同,在這裡就不再贅述。

建樹**:

void add(string s)

//將與根相連的節點的fail指標指向根節點並將它們入隊

while(q.size())

else

ac[now].son[i]=ac[ac[now].fail].son[i];

}//重複第4、5步

}

三、字串匹配字串匹配的思想與kmp基本相同,實現方式與trie上查詢字串類似。將文字串從頭到尾一位一位在trie上查詢,對於每乙個節點,若沒有被遍歷過,沿著它的fail指標走,直到根節點或乙個已遍歷過的點。對於路徑上的所有點,將答案加上它的結尾標記,即當前節點為幾個字串的結尾,然後將其結尾標記改為-1,以顯示其已遍歷過。

還是以這個圖為例:

若文字串為yasherhs,則:

對於y,a,trie中沒有對應的路徑

對於s,h,e,在trie中可以沿著root-s-h-e這條路徑走到第四層節點e,答案加1,沿著其fail路徑向上可以走到第三層節點e,答案加1;

對於r,此時指標指向第四層節點e的兒子指向的節點,也就是其fail指標指向的第三層節點e,隨後指向右下角節點r,答案加1;

對於h,s,因為已經遍歷過了,因此不會再進行遍歷

為什麼走到乙個已遍歷過的點也要停止呢?因為若乙個節點已被遍歷,則沿著它的fail指標走直到根節點的這條路徑上的所有節點一定都被遍歷過了,若在走一遍則屬於浪費時間,因此直接停止即可。

字串匹配**:

int get()

ac[n];

void add(string s)

//輸入模式串並插入trie

ac[0].fail=0;//將根節點的fail指標指向自己,其實這步可以不要,因為預設就是0

build();//求fail指標

cin>>f;

cout<

習題:

AC自動機詳解

最近真是太頹了,做了一堆板子題,現在對一些知識點順便來個總結記錄 大家應該都知道kmp和trie樹吧,不懂的可以看我部落格或到網上自己動手尋找資料。ac自動機是乙個很好的東西,這是因為它的名字很好它能夠在有多個模式串的時候進行全文匹配,這十分方便地擴充套件了kmp的功能,實際上它的思路與原理與kmp...

AC自動機詳解

首先,ac自動機,不是 自動accepted機,這是乙個多模字串匹配演算法,學習這個演算法,首先要熟悉kmp演算法這個單模字串匹配演算法,然後,我們知道有個高效的多模字串匹配演算法,叫字典樹,它處理的是一些單詞在乙個句子裡出現了幾次,但假如不是在乙個句子裡,而是在乙個字串裡呢?那它就顯得很弱了,所以...

AC自動機詳解

include include include include include include include include using namespace std typedef long long ll const int maxn 2 1e6 9 int trie maxn 26 字典樹 i...