AC自動機入門

2021-07-30 06:01:22 字數 1638 閱讀 2100

kmp演算法可以解決單個模式串比較的問題,如果模式串有多個,那麼kmp演算法的效率就不盡如人意了。

一種可行的辦法是ac自動機,解決多模式串匹配的問題。

ac自動機和kmp演算法的思想是相同的,就是跳過不必要的移動,直接到失配的位置所對應處。只是ac自動機是以trie(字典樹)為基礎的。

同kmp演算法類似,ac自動機的演算法過程大致如下:

1.計算trie樹中每個節點失配後直接指向的位置

2.主串匹配

不妨結合kmp演算法的next陣列考慮(由於trie樹中有next這個名稱,為避免重複,trie上用fail來表示失配後指向的位置,fail的作用和kmp演算法中的next是相同的作用),fail同樣應當表示「最長公共前字尾」,這樣才能跳過不必要的移動。不同的是,kmp是線性處理,而ac自動機需要的是在trie樹上。

不難發現,計算fail的方法如下:

在trie上從根節點開始bfs,根據bfs序來依次處理每乙個節點(為啥不是dfs呢?因為既然是最長公共前字尾,那麼每個節點的fail指向的節點深度應該小於自己,bfs的順序就可以保證)。對於節點x,從它的父親節點的fail節點開始,與kmp類似,一直往fail位置跳,直到當前節點的字元與x的字元相同。不難發現,這就是節點x所代表的字首的「最長公共前字尾」。特別的,如果沒有找到fail,就把節點x的fail賦成根節點(這樣就不會造成影響)。

void create_fail () }}

}

主串匹配的時候,與kmp類似,就一直往fail跳,直到找到匹配當前字元的位置,如果沒有就會隨fail回到根節點重新來。

int match() 

}return ans ;

}

這裡用hdu2222模板給出完整**

#include 

#include

#include

#include

#include

using

namespace

std ;

const

int maxn = 60 ;

char s[10010][maxn], pat[1000010] ;

struct node

} *h, *p, *q ;

int n, m, tot, len[10010] ;

void create_trie ( int x )

}p->tim ++ ;

}node *q[100010] ;

void create_fail () }}

}int match()

}return ans ;

}void check ( node* now )

int main()

for ( i = 1 ; i <= n ; i ++ )

create_trie(i) ;

create_fail() ;

scanf ( "%s", pat+1 ) ;

m = strlen(pat+1) ;

printf ( "%d\n", match() ) ;

}return

0 ;}

吐槽:幸好我先學了kmp,這樣ac自動機就沒那麼難了

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樹結構 kmp轉移思路 ac自動機組要由三個部分組成 trie樹的建立 fail指標的匹配 對ac自動機的詢問 每次建立自動機會有一次初始化 ac自動機類 struct node node結構體 struct ac voi...

AC自動機演算法

ac自動機簡介 首先簡要介紹一下ac自動機 aho corasickautomation,該演算法在1975年產生於貝爾實驗室,是著名的多模匹配演算法之一。乙個常見的例子就是給出n個單詞,再給出一段包含m個字元的文章,讓你找出有多少個單詞在文章裡出現過。要搞懂ac自動機,先得有字典樹trie和kmp...