AC自動機的實現原理

2021-06-11 23:42:04 字數 2323 閱讀 4538

最近學習ac自動機,看了不少講解ac自動機的文章,幾乎都是在講如何操作。估計不少人學習時像我一樣在想ac自動機演算法為什麼能實現多模式串匹配操作。如下是我的思考成果,如有漏洞,歡迎指正。

建立trie樹比較容易,構造fail指標其實是同樣的匹配過程,只要理解query()也就都明白了,下面主要來說說query()是如何完整地查詢出所有的模式串的。

對於給定的長字串,查詢有多少模式串在裡面出現過。query函式依次讀入長字串裡的字元,而匹配某一模式串操作是在query函式讀入長字串的某一字元時發生的。query依次讀入字元,不受其他操作影響(無論有沒有發生匹配query都老老實實地乙個接乙個地讀串)。每讀入長字串中的乙個字元str[i],便需要求這樣乙個子串,設為s[i](即str(k...i)串),滿足如下關係:

該子串是某一模式串的字首,且是所有模式串中的最長字首, 即不存在某字串的字首為str(k1...i),k1

現在要做的是每讀入乙個str[i],求出它的最長字首(s[i])。以下是求s[i]的方法:

s[i]=s[i-1]+str[i]-------------------->>>>當前正在匹配的模式串的下乙個字元==str[i]

(顯然s[i-1]表示上一狀態即掃瞄到str[i-1]的最長字首);

s[i]=houzhui(houzhui...(houzhui(s(i-1))))+str[i]---------------->>>>當前正在匹配的模式串的下乙個字元!=str[i]

(houzhui()函式取的串滿足如下條件1當前正在匹配串的字尾;2其他模式串字首;3滿足條件1、2的最長的串。描述起來很費勁,但你觀察已經建立好的trie樹和fail指標的特性,發現所謂houzhui()操作是水到渠成的(思考一下,其實trie樹有很多隱含特性的)。僅需第75、76行**

。顯然,取字尾操作是有截止條件的,截止條件就是當取得的字尾(設為l(j...k))是某字串(設為l1(1...m))的字首,且元素l1(k-j+1)==str[i],那麼l(j...k)+str[i]便是我們所求的s[i]。)

這個看起來像不像dp中的遞推關係式?把每一步求解str[i]看做乙個狀態,每一步str[i]最長字首s[i]的求解依賴於上一狀態str[i-1]的解,這應該就是ac自動機中的dp思想。

求解出每一狀態的最長字首還遠沒有結束,現在我們知道了當前狀態下(即當前str[i]下)的最長字首和str[i]這個字元,要求的是在這個str[i]下發生匹配的模式串。現在做如下討論:

若某一模式串在str[i]狀態下被匹配,則該模式串的末尾字元==str[i],且之前的字元是str[i]的最長字首的某一字尾。

下面就查詢滿足上述關係的模式串進行匹配操作,也就是依次查詢str[i]下的最長字首的最長字尾,該操作便是(之前看講解對此都是含糊不清的)。

while(temp!=root&&temp->count!=-1)
看是否有模式串恰好是那個str[i]下的最長字首的字尾。若有,則該串被匹配,不要停,繼續找字尾,直到字尾為0,即fail指向了root。(至於為什麼繼續找應該不需要解釋了)此處查詢操作再次用到了fail指標,fail指標的作用就是幫助我們找字尾,當然,準確地說是同樣出現在模式串中的字尾。

貼出**(hdu2222):

#include#include#includeusing namespace std;

struct node*q[500001]; //用作建trie樹時廣搜的佇列

char keyword[51];

char str[1000001];

int head,tail;

void insert(char str,node *root)

p->count++;

}void build(node *root)

p=p->fail;

}if(p==null)

temp->next[i]->fail=root;

}q[head++]=temp->next[i]; //入佇列

}} }

}int query(node *root)

i++;

} return cnt;

}int main()

build(root);

scanf("%s",str);

printf("%d\n",query(root));

} return 0;

}

AC自動機原理

ac自動機原理 摘自大牛 一 構建ac自動機 同樣我也用網上的經典例子,現有say she shr he her 這樣5個模式串,主串為yasherhs,我要做的就是哪些模式串在主串 現過?1 構建trie樹 如果看過我前面的文章,構建trie樹還是很容易的。2 失敗指標 構建失敗指標是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...