一:概念
首先簡要介紹一下ac自動機:aho-corasick automation,該演算法在2023年產生於貝爾實驗室,是著名的多模匹配演算法之一。乙個常見的例子就是給出n個單詞,再給出一段文章(長度是m),讓你找出有多少個單詞在文章裡出現過。要搞懂ac自動機,先得有字典樹trie的基礎知識(也有人說需要kmp的知識,我覺得暫且不要理會這個。但是在看這篇文章之前,trie字典樹,你是必須要先搞懂.與其他字元匹配不同,kmp演算法是單模式串的字元匹配演算法,ac自動機是多模式串的字元匹配演算法。
二:演算法過程(三步走)
舉個例子,假如現在給出5個模式串:say she shr he her
主串是:yasherhs
現在問你,這5個模式串有幾個出現在主串裡的?
ok,現在就拿這個例子來完成這個演算法的過程。
第一步:構建trie樹,這很簡單的了。構建好後,出現下圖:
第二步:構建失敗指標
構建失敗指標是ac自動機的核心所在,玩轉了它也就玩轉了ac自動機,失敗指標就是,當我的主串在trie樹中進行匹配的時候,如果當前節點不能再繼續進行匹配,那麼我們就會走到當前節點的fail節點繼續進行匹配。
構造失敗指標的過程概括起來就一句話:對於root的兒子節點,fail指標直接指向root,其他的所有節點(用到了bfs和佇列),設這個節點上的字母為c,沿著它父親的失敗指標走,直到走到乙個節點,它的兒子中也有字母為c的節點。然後把當前節點的失敗指標指向那個字母為c的節點。如果一直走到了root都沒找到,那就把失敗指標指向root。
構建好後,如下圖:
針對圖中紅線的」h,e「這兩個節點,我們想起了什麼呢?對」her「中的」e「來說,e到root距離的n個字元恰好與」she「中的e向上的n個字元相等。
第三步:模式匹配
匹配過程分兩種情況:
(1)當前字元匹配成功,表示從當前節點沿著樹邊有一條路徑可以到達目標字元,此時只需沿該路徑走向下乙個節點繼續匹配即可,目標字串指標移向下個字元繼續匹配;
(2)當前字元不匹配,則去當前節點失敗指標所指向的字元繼續匹配,匹配過程隨著指標指向root結束。重複這2個過程中的任意乙個,直到模式串走到結尾為止。
注意:主串所有字元在匹配完後都必須要走fail節點來結束自己的旅途,相當於乙個迴旋,這樣做的目的防止包含節點被忽略掉。
見下圖,比如:我匹配到了"she",必然會匹配到該字串的字尾」he",要想在程式中匹配到,則必須節點要走失敗指標來結束自己的旅途。
三:完整**
#include
#include
#define max 26//假設只出現26個小寫英文本母
#define row 4
#define column 10
using namespace std;
char pattern[row][column] = ;
char *s = "sdmfhsgnshejfgnihaofhsrnihao";
struct node
};class actree
void add(const char *ch, int index); //第一步
void nodetoqueue(node *node, queue &q); //
void buildfailpointer(); //第二步
void acsearch(const char *s); //第三步
};int main()
cout << endl << endl;
cout << "匹配結果如下:\n";
cout << "位置\t" << "編號\t" << "模式\n";
tree.acsearch(s);
return 0;
}void actree::add(const char *ch,int index)
p = p->next[k];
} p->index = index;//注意,在此保證輸入的模式串不重複,否則index會被覆蓋
}void actree::nodetoqueue(node *node, queue &q) }}
void actree::buildfailpointer()
} node *parent, *p;
char ch;
while (!q.empty())
else
else
parent = parent->fail->parent;
}} }
}void actree::acsearch(const char *s)
else
}} while (p != root)
}四:資料測試
暖 墟 AC自動機 AC自動機的總結與運用
kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...
AC自動機 建立nlogn個AC自動機
string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...
kmp與ac自動機
xj比賽做到一道字串題,結果發現想打個字串匹配都只會n 2了,又一次忘記了kmp 想必是當初學這玩意心理陰影面積太大了。這裡再梳理一遍kmp和ac自動機 以便下次再忘了有地方看.kmp 用於處理對於字串s,想知道它在另外某個串哪些位置出現的問題,先做預處理得到乙個失配陣列,這個陣列第i位表示s的前i...