AC自動機詳解

2021-08-19 10:27:44 字數 2357 閱讀 7547

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

aho-corasick automaton,該演算法在2023年產生於貝爾實驗室,是著名的多模匹配演算法

先講一下ac自動機的工作流程吧:

1、以所有模式串構建一棵trie樹(字典樹)

2、構建每個節點的fail指標

3、與文字串進行匹配

第乙個流程就不用講了吧,就是字典樹的模板,重點講的是第二個流程——fail指標的構建,每個節點的fail指標,就好比kmp裡面模式串的next陣列,當這個點失配時,應該跳到哪個點繼續匹配,不一定是跳到這乙個單詞的前面,有可能會跳到別的單詞上,某個節點的fail指標構建的根據是:root到這個節點的路徑的所有字尾中,剛好是某個單詞的字首的字尾中的最長的那個,這樣說可能比較抽象,來看看下面這幅圖吧:

這是構建8號節點的fail指標時的樣子,可以發現,1到8的路徑的字尾分別是:cab、ab、b  ,其中只有ab這個字尾剛好是某個單詞的字首,也就是ab這個單詞,於是,8的fail指標就指向3

那麼fail指標怎麼求呢?可以模擬一下kmp的next陣列是怎麼求的,在kmp演算法中,next[i]是由next[i-1]得到的,那麼同樣的,某個節點的fail指標也可以由它的父親節點得到,在kmp裡,我們使乙個j=next[i-1],當s[j+1]!=s[i]時,j=next[j],直到j=-1或s[j+1]=s[i],同樣的,在ac自動機裡面,我們還是讓j=tree[ree[i].fa].fail,並且加乙個c,讓c=i和i的father之間的邊上的字元,然後如果j沒有c這個兒子,j=tree[j].fail,直到j=-1或j有c這個兒子了,就讓i的fail指向j的c這個兒子,因為每乙個節點的fail都可能由層次比他淺的節點得到,所以我們需要用廣度優先搜尋,來遍歷每個點,如果還不理解,可以結合kmp演算法來想一下就好了

**如下:

void makefail()//注意要使tree[0].fail=-1,和kmp裡面讓next[0]=-1是乙個道理 

}

那麼匹配起來就很容易了,我們以洛谷上的一道模板題作為例子,那麼我們建樹**如下:

void build(char ss,int z)

else//如果匹配成功

if(ans==n)break;//小優化,已經找到全部單詞就退出

}

完整的**:

#include #include struct node

}tree[1000010];

int n,len=0;

char s[1000010];

bool v[1000010];

int ch(char x)

void build(char ss,int z)

}char wbc[1000010];

int main()

tree[0].fail=-1;

makefail();

int i=1,j=0,ans=0;

scanf("%s",wbc+1);

int m=strlen(wbc+1);

memset(v,false,sizeof(v));

while(i<=m)

else

if(ans==n)break;

}printf("%d",ans);

}

update on 2020.6.17:寫了個更順眼的版本:

#include #include #include #define maxn 1000010

int n; char s[maxn];

struct node

}*root=new node(null);

void ins(int len)

node *q[maxn];int st=1,ed=0;

void makefail() }}

int main()

else now=now->next[s[i++]-'a'],now->mat=1;

} int ans=0;for(int i=ed;i>=1;i--)

q[i]->fail->mat|=q[i]->mat,ans+=q[i]->mat*q[i]->end;

printf("%d",ans);

}

AC自動機詳解

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

AC自動機詳解

首先,看清楚了,這是ac自動機不是自動ac機 引用ac自動機模板題上的一句話 ovo在學習ac自動機之前,應該先掌握一下兩個前置技能 ac自動機,通俗地講,就是在trie上跑kmp。ac自動機利用trie的性質和kmp的思想,可以實現字串的多模匹配。kmp是單模匹配,而它與ac自動機最大的區別就在f...