AC自動機學習小記

2021-08-21 02:37:44 字數 2020 閱讀 8022

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

其實ac自動機就是tire加上kmp。

乙個簡單的問題(hdu2222):給出多個模式串,在給出乙個文字串,問模式串在文字串中出現了多少次。

最簡單的做法就是將模式串加入的tire中,在用文字串逐位去匹配。

思考kmp的做法,借助失配指標利用已匹配的字串,將時間複雜度降到o(

n)o (n

)。 考慮將失配指標放到tire上

我們定義str(x)表示tire上節點x所表示的串,失配指標fail[x]所指向的節點y滿足str(y)為str(x)的最長字尾。

fail指標大概就長這個樣子。

得到fail以後我們如何進行匹配?以圖中的tire為例,對」heshis」進行匹配。

首先我們會沿著tire的邊走到2點,匹配到乙個模式串he,發現下乙個點失配,那麼我們沿著fail邊跳到0。繼續沿著邊走,到4點失配,沿著fail邊走到1點。向下走到7點匹配第二個模式串his。

這樣我們就可以大概想到ac自動機的匹配方式:沿著tire的邊走,失配就往fail邊走。

code:

int query(char s)

}return tot;

}

構造ac自動機的fail邊,需要按照bfs序來做。

why?fail邊指向的是最長字尾,那麼str(fail[x])應該要比str(x)短。這樣就保證了比str(x)要短的串已經構造完了。

現在我們有乙個點x,以及它的父親y,已知fail[y],如何求fail[x]。

str(fail[y])+c(乙個字元)如果等於str(x),那麼fail[x]就是c所表示的y的兒子。

如果不相等,那麼我們令y=fail[y],繼續進行上面的操作。

code

void build() 

while (!d.empty())

d.pop();}}

假設有

n n

個模式串,平均長度為

l' role="presentation">l

l;文章長度為

m m

。 建立trie樹:o(

nl)' role="presentation">o(n

l)o(

nl)建立fail指標:o(

nl) o(n

l)模式匹配:o(

m(l)

) o(m

(l))

(之所以要乘以乙個

l l

,是因為在統計的時候需要順著鏈回溯到root結點)

hdu2222

一道ac自動機模板題

#include 

#include

#include

#include

using

namespace

std;

const

int n=1e6+10,m=1e6+10;

queue

d;char s[n];

int n;

struct ac

void insert(char s)

sum[x]++;

}void build()

while (!d.empty())

d.pop();}}

int query(char s)

}return tot;

}void init()

}aca;

void work()

aca.build();

scanf("%s",s);

printf("%d\n",aca.query(s));

}int main()

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...

AC自動機 學習筆記

是一種數學模型,大概就是由一堆狀態和狀態轉移規則等東西構成,能與外界交換資訊,並改變動作。這個是理論上的東西,了解就行,對ac自動機的理解沒有大影響。通俗的講就是在trie上做kmp,處理多模式串匹配問題。trie 的每個結點就是乙個狀態,根結點是初始狀態。ac自動機的行為被定義為一下3個函式 1....

AC自動機學習總結

久聞ac自動機的大名,終於,在準備好kmp和字典樹之後,開始學習這個看起來高大上的演算法了。多餘的寫題的時候在補充吧,學完之後發現他的板子並不難,理解也不算太難,網上有很多種寫法,近期研究一下,一些 的常數的問題。洛谷有道題,直接就是板子 參考不知名大佬的板子 看了好多人的板子了 然後放棄指標,因為...