對ac自動機的一些個人理解

2021-07-28 23:29:30 字數 2857 閱讀 9841

這裡用的是kuangbin的ac自動機的板子。

ac自動機,怎麼說呢,其實就是trie樹(字典樹)加上kmp的演算法思路。

int createnode()

end[tot++]=0; //表示模式串的終端節點,用來標記某個模式串

return tot-1;

}void init()

void insert(char *str)

cur=next[cur][str[i]-'a'];

}end[cur]++;

}

這一段其實就是建立trie樹的**,不懂的話可以學一下。

其實就是用next二維陣列來模擬建樹。

接下來就是ac自動機的核心部分,fail指標的構建,

這裡的fail函式其實就是類似kmp演算法的next函式,如果我們的模式串在tire

上進行匹配時,與當前節點的關鍵字不能繼續匹配的時候,就應該去當前節點的

fail指標所指向的節點繼續進行匹配。

這裡盜用一些別人的配圖

例如模式串有,say,she,shr,her.

上圖就是根據這些模式串來建立trie樹,紅圈其實就是上述的end陣列,

表示這條路徑上到這個節點所組成的字串是模式串的其中乙個。

接下來我們就要根據這個圖還有**來建立fail指標。

**3-5行是處理模式串的第乙個字元,第一層的fali指標都是指向root節點的。

如圖,按照字典序,h的fail指標指向rt,如圖中的虛線1(虛線就是該節點fail指標的指向),

然後把h入隊,接著處理s.由於第一層,所以s的fail指標也是指向root節點,如圖中的虛線2,

然後把s入隊。佇列中就有(h,s).

第一層出現到這裡就結束的。

接著就出現佇列中的節點。首先是h,h的next節點有e,當for迴圈處理到e這個節點時,

那麼就進行19行~20行的操作,找e的fail指標,那我們就返回到第一層尋找有沒有

之前有沒有出現過e這個節點,發現沒有,那麼e這個節點的fail指標就指向root節點,

也就是圖中的虛線3,然後e入隊,這時候處理完h所以的next節點,佇列中現在有(s,e),

接著處理佇列中的s節點,s的next節點有a,h,a和上面的e是同理的,這裡就不說,

記得找到a的fail指標,要把a入隊哦。

接著處理h,我們發現上一層(也就是第一層)出現過h這個節點,那麼h的fail指標

就指向第一層的h節點,也就是虛線5,

然後h入隊,這時候佇列中有(e,a,h),其實接下來的步驟和上面是一樣的,依照

迴圈,最後找出所有節點的fail指標,

那麼ac自動機最核心的部分講完了。

接著就是模式串匹配了。

模式串:say,she,shr,her

主串:yasherhs

int query(char *buf)

}return res;

}

首先呢,y和a在trie樹沒有對應的路徑,不會執行while迴圈,所以直接跳過。

接著就s,h,e這三個了,由於s,sh這都不是模式串,所以res還是0,

當到e這個節點的時候,這時候cur是在she這條路徑的e節點上,恰好she是乙個模式串,

那麼res+=1,然後把end[temp]變成0是為了防止後面會出現同樣的模式串。

接著我們就跳到e的fail指標所指向的節點,我們會發現,當前節點也是模式串

的乙個,即he,那麼我們已經找到兩個模式串she,he了。

接著到r了,這時候的r的節點是在her這條路徑上的,剛好也就是

模式串的其中乙個,那麼res就+1.可能有小夥伴就會疑問了,你之前的路徑不是she

上的嗎,怎麼會跑到her這條路徑上呢。

其實這個在建立fail指標上就有了。

if(next[cur][i]==-1)

解釋就在這裡,剛好she這條路徑上的下乙個節點為-1(即e的下乙個節點並不是r),

那麼我們就會條到e的fail指標指向的節點上繼續匹配,正好he這條路徑上有r,

所以我們就匹配了模式串her了,是不是很巧妙,我也覺得很巧妙。

接著的h,s都找不到對應的模式串的,匹配結束,那麼res為3,匹配串分別是she,he,her.

匹配的過程有兩種:

(1)當前字元匹配,表示從當前節點沿著樹邊有一條路徑可以到達目標字元,此時只需沿該

路徑走向下乙個節點繼續匹配即可,目標字串指標移向下個字元繼續匹配;(2)當前字元

不匹配,則去當前節點失敗指標所指向的字元繼續匹配,匹配過程隨著指標指向root結束。

重複這2個過程中的任意乙個,直到模式串走到結尾為止。

大概ac自動機入門就是這樣子啦,如果有錯的地方,希望大家提出來,一定會改的。

AC自動機理解

對於ac自動機可能有的疑問。首先上 該 使用char型陣列儲存,事實上string也完全可以。includeusing namespace std char s 1000005 struct tree 字典樹 ac 1000000 trie樹 int cnt 0 trie的指標 inline voi...

AC自動機的一點理解

fail 指標 指向最長的在 tire 裡出現的字尾 比 tire 多出來的子邊 原來的 tire 我們失配後又得返回根結點再次匹配,而加入這些邊後只需要花 strlen s 就能實現所有匹配 跑 tire 圖 能跑到乙個結點,該結點所代表的串能被文字串表示 問題1 多個模式串,乙個文字串,有幾個模...

暖 墟 AC自動機 AC自動機的總結與運用

kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...