AC自動機(字串多模匹配)

2021-08-21 14:29:50 字數 1437 閱讀 5144

非常經典的乙個關於字串匹配的演算法

前置技能是:kmp和trie

重難點是fail指標(其實挺簡單的)

其實不一定要會kmp,只要會它的思想就行了。

所謂fail邊,其實就是乙個失敗指標,與kmp的next指標(類似於失敗指標,詳見我的kmp的部落格裡的p陣列)不同的是,next是對於乙個串而言的,而fail則是對全部串都通用,而且是在trie上操作的。

fail[i]表示某乙個節點,根節點(以下簡稱root)到另外乙個節點所組成的字串,可以完全匹配與i的祖先到i所組成的字串,這樣說有點玄學,給個圖深入了解一下吧。

如圖,這是一棵trie,然後我們人工腦補它們的fail邊。

為什麼只連了c,d呢,想想看,root到編號為5的c所構成的串就是「c」,正好符合編號為2的c它自己。

還有root到編號為6的d,構成了「cd」,編號為3的d的祖先到編號為3的d所構成的,也正好是「cd」。

但是有的節點沒有匹配怎麼辦呢,那就直接把fail邊連到root就好啦,於是圖變成了這樣。

ok,現在我們想一想怎麼連fail邊。

對於乙個節點,如果它的fail邊不連向root,那麼它所連向的節點可能是它父親的fail所連向的節點的兒子,因為只有在前面都匹配了的情況下,才能去匹配這個節點是否也可以嘛。

為什麼是可能呢,因為有可能匹配不了,怎麼辦呢?那就從它父親的fail邊指向的節點的fail邊指向的節點再去找,依次類推,一直到到root為止。

ps:在root這個點也要再匹配一次!root的fail邊指向自己。

給出程式了解一下。

while(h0)then

begin

inc(t);

d[t]:=trie[d[h],i];

if(d[h]<>0)then

begin

x:=fail[d[h]];

while(trie[x,i]=0)and(x<>0)do x:=fail[x];

//一直去匹配,用它父親的fail去找

if(trie[x,i]<>0)then

begin

fail[d[t]]:=trie[x,i];

inc(into[trie[x,i]]);

//記錄下入度,後面有用的

end;

end;

end;

end;

end;

一定要學會trie先!!!!(不會可以去看我的trie)

ac自動機 匹配最長字首 多模匹配 AC自動機

精確的字串匹配演算法有 單模匹配演算法,比如,kmp bm演算法等 和 多模匹配演算法,比如,wu manber ac演算法等。ac演算法 aho corasick 是kmp演算法向多模式串情形的擴充套件,該演算法使用一種特殊的自動機,即ac自動機。ac自動機由一組模式串p生成,是trie的擴充套件...

AC自動機 多模匹配演算法

寫了個模板題,加強版借鑑大佬的 前置技能kmp 感覺沒啥用主要是思想 字典樹。p3808 模板 ac自動機 簡單版 include include include include include include include include using namespace std typedef ...

AC 自動機 多模式串匹配

上的敏感詞過濾是怎麼實現的呢?實際上,這些功能最基本的原理就是字串匹配演算法,也就是通過維護乙個敏感詞的字典,當使用者輸入一段文字內容後,通過字串匹配演算法來檢查使用者輸入的內容是否包含敏感詞。bf rk bm kmp 演算法都是針對只有乙個模式串的字串匹配演算法,而要實現乙個高效能的敏感詞過濾系統...