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