ac自動機與kmp演算法,都是用於優化字串匹配的演算法。
kmp演算法應用於單模式串的匹配。
而ac自動機是應用於多模式串的匹配。
但並不意味著kmp演算法可以被完全取代(儘管兩者的演算法思想本質上是一樣的)。
相對而言,kmp演算法比較容易一些。
首先,考慮如何暴力匹配?很顯然,可以以主串的任意乙個位置開頭,然後開始匹配,失配後,再找下乙個位置開頭。
這樣的複雜度顯然是o(n*m)的。非常低劣。
而kmp演算法則是用於優化這個過程的。顯然,每次重新匹配時,如果能利用之前匹配的資訊,那麼就會節約很多時間。這裡就要引入fail陣列。fai
li
fail_i
faili
表示與字首i
ii擁有相同字尾的,最靠後的位置。這樣如果在i號位置失配,那麼可以跳到其fail指標的位置,繼續匹配。
這樣做的複雜度很顯然就是o(n+m)的。
板子:
void
build
(int x)
else
j=fail[j];}
}void
solve
(int x)
else
j=fail[j];if
(j==len[x]
) ch[i-len[x]]|
=(1<<
(x-1))
;}}
1、bzoj4974字串大師
2、bzoj3670動物園
3、bzoj4560字串覆蓋
4、bzoj4820硬幣遊戲
5、bzoj2384[ceoi2011]match
ac自動機則是將fail指標帶到了trie樹上。
原理還是一樣的。fai
li
fail_i
faili
與i
ii擁有相同字尾的深度最大的點。
每次失配後也是往著fai
li
fail_i
faili
跑。1、bzoj1444有趣的遊戲
2、bzoj1559密碼
3、bzoj4861魔法咒語
板子:
struct nodetree[maxn]
;node* rt=tree,
*ncnt=tree;
void
insert
(node *now,
char
*c,int id)
int d=
*c-'a';if
(now-
>ch[d]
==null
)insert
(now-
>ch[d]
,++c,id);}
queue> q;
void
build()
while
(x!=rt&&x-
>ch[i]
==null
) x=x-
>fail;
if(x-
>ch[i]
==null
) now-
>ch[i]
->fail=rt;
else
now-
>ch[i]
->fail=x-
>ch[i];}
}}
AC自動機模版 字串
ac自動機主要用於解決多模式串的匹配問題 具體指的是 如下圖中 模式串 p中有多個 字串,問這些字串在 主串s的出現的總次數 是字典樹 trie樹 的變種,一種偽樹形結構 主體是樹形的,但是由於加入了失敗指標,使得它變成了乙個有向圖 以當前節點為終點的 模式字串 的數量 int fail 1 fai...
kmp與ac自動機
xj比賽做到一道字串題,結果發現想打個字串匹配都只會n 2了,又一次忘記了kmp 想必是當初學這玩意心理陰影面積太大了。這裡再梳理一遍kmp和ac自動機 以便下次再忘了有地方看.kmp 用於處理對於字串s,想知道它在另外某個串哪些位置出現的問題,先做預處理得到乙個失配陣列,這個陣列第i位表示s的前i...
字串 2 AC自動機
ac自動機,其實就是trie樹與kmp的結合,且有dfa 有限狀態機 的性質.理解的關鍵點 1.fail指標 起到回溯作用 2.每次匹配都是主串不動,移動指標now去回溯找字尾的字首 3.乙個優化點,將null指向root 編碼更簡單.考察時一般也會問道dfa的性質.ac自動機解決問題 1.多模式串...