AC自動機(模板不帶指標)

2021-08-20 23:31:23 字數 2469 閱讀 8259

之前學ac自動機的時候學長給的模板是帶指標的,然而我並沒有學過指標。上網搜到的**也大部分都是帶指標的,少數的幾個還有不對的【難過】,後來綜合好幾個板子寫出了自己的模板,一方面自己記下來防止以後忘了,另一方面也造福廣大不會指標的oier們。

所以,ac本來是阿霍-科拉斯克的意思,跟你們的wa,re,tle,ce,mle......都沒有關係。

給出幾個字串,其中乙個主串,乙個模式串,詢問模式串在主串中出現了幾次,這種操作叫作匹配。這樣的問題一般會採用kmp演算法解決。

如果模式串不是乙個,而是多個呢?這就叫做多模匹配,就要用到我們今天學到的ac自動機演算法啦!

ac自動機可以簡單的被認為是在一棵樹上跑kmp的過程。

好的我假設你們不會kmp。

我們先把所有的模式串建成一棵trie。

然後需要定義乙個fail陣列(相當於kmp中的next),它代表了如果在當前模式串中失配應該跳到樹上的哪乙個結點繼續匹配。所以fail結點代表的字串應該是這乙個節點代表的字串的最長字尾。因為字尾才可以保證fail結點代表的字串都可以在主串中匹配,而最長字尾可以保證不會落下任何乙個可以匹配的模式串。

我們以say,****,she,he,her,his的一棵trie為例,它所構建出的fail指標應該是這樣的:

其他沒有畫出來的指標都指向根。

假設我們用sasher這個字串到上圖中去匹配,那麼它走過的路徑是這樣的:root--s--a--root--s--h--e--e--r。

在這個過程中,經過了e、r兩個終止節點,並且我們發現,e、r兩個節點所代表的字串she、her都在主串中出現過,所以我們得出,如果匹配過程中經過了終止節點,那麼這個終止節點所代表的字串是主串的子串。於是多模匹配的任務就完成了。

首先在構造fail指標之前,我們需要先了解它的幾個性質。

1、根的所有子節點的fail都指向根。

2、在乙個節點不斷向上跑fail的過程中,節點的深度是不斷減小的。

3、如果a節點的fail指向了b節點,那麼a節點的t兒子的fail指向b節點的t兒子。

構造fail指標主要利用的就是第三條性質。翻譯成**就是

fail[c[now][i]]=c[fail[now]][i];
額。。。好醜啊我不知道為什麼是黑的。。。

c[now][i]的意思就是now這個節點的i兒子。也就是說,now節點的i兒子的fail是now節點的fail的i兒子。

下面是構建fail指標的全部**

void build()

while(!q.empty())

else c[now][i]=c[fail[now]][i];//如果兒子i不存在,就連一條虛擬的邊

}} }

最後乙個else的地方可能有些人不懂,我們下面來說這個操作。我們把它叫做ntr。

ntr為日文「寝取る」的被動形「寝取られ」的羅馬拼音縮寫:ねとられ(ne to ra re)→ ntr。中譯即「被他人強佔配偶或物件」、被別人戴綠帽。日語解釋:ntrとは、「寝取られ」の略稱で隠語である。ストーリー屬性の一つ「寝取られ」の隠語。在日文中也有用ntrr來表示「寝取られ」(物件被人睡)、ntr來表示【寝取り】(睡了別人的物件)的用法,但並不常用,一般都是用「ntr」來直接表示【寝取られ】。

嗯好的我們先不要管上面那一段。當now的兒子i不存在時,如果我們要查詢的乙個字串在now後面有乙個i字元,我們的程式需要跑到now的fail找fail的i兒子,但是如果fail也沒有i兒子就需要繼續往上跑。容易想到,如果連續許多個fail都沒有i兒子的話,我們可能需要跑許多次的fail,這就使我們的時間非常的不美妙。於是,ntr這個操作,就是給now提供乙個虛擬的i兒子,c[now][i]這條邊實際上是連到了它的fail上。

這個步驟實際上應該是在構造fail指標之前的,但是因為fail指標是ac自動機的精髓,所以我們把這個步驟放到後面來說。

首先你一定要知道trie樹是什麼。trie樹就是一棵節點存字元,從根到每個終止節點的路徑是乙個字串的樹,比如前面的圖上就是一棵trie。在ac自動機上插入字元的操作和trie樹上的一模一樣,所以就不贅述了,直接貼**。

int idx(char s)

void insert(char s)

void insert(char s)

{ int len=strlen(s);

int now=root;

for(int i=0;ip.s:這篇文章是乙個多月前就開始寫了,開始寫的第一天正好是學校另外兩個oier(初中的)中考的日子,所以打算在文章末尾奶他們ak的,然而一直也沒有寫完【捂臉】。。。(沒關係啦反正他們乙個已經ak考了乙個【假的】市狀元,另乙個全市三十幾名來著,據說是被我奶死的)正好今天是noip98天,也就是我退役100天倒計時,就在這裡祝同校的oier們noip2018ak吧!(noi2019au候選人)!!!!!

AC自動機模板

ac自動機模板 ac自動機模板 使用方法 1 init 初始化函式 2 insert str 插入字串函式 3 build 構建ac自動機 4 query str 返回出現的字串個數 使用需注意事項 1 注意輸入的字元的範圍,需對next和其二維大小及相關引數進行更改 2 注意next fail和e...

AC自動機模板

ac自動機主要是用於多模式串的匹配問題,按照我的理解,ac自動機就是在tire樹上實現kmp演算法,由於ac自動機加入了失敗指標,所以可以把他看成乙個狀態轉移的圖。給出模板 include include include include includeusing namespace std cons...

模板 AC自動機

我覺得ac自動機的難點和核心是構建失敗指標,父親的失敗指標的兒子 son2 中有和兒子 son1 相同的,即為son1的失敗指標 例 還是有個不懂的地方 第90行,跪求大佬賜教 include include include include include include include inclu...