AC自動機原理

2021-09-30 10:43:04 字數 1920 閱讀 6090

ac自動機原理:

摘自大牛

一:構建ac自動機

同樣我也用網上的經典例子,現有say she shr he her 這樣5個模式串,主串為yasherhs,我要做的就是哪些模式串在主串**現過?

1: 構建trie樹

如果看過我前面的文章,構建trie樹還是很容易的。

2:失敗指標

構建失敗指標是ac自動機的核心所在,玩轉了它也就玩轉了ac自動機,失敗指標非常類似於kmp中的next陣列,也就是說,

當我的主串在trie樹中進行匹配的時候,如果當前節點不能再繼續進行匹配,那麼我們就會走到當前節點的failnode節點繼續進行

匹配,構建failnode節點也是很流程化的。

①:root節點的子節點的failnode都是指向root。

②:當走到在「she」中的」h「節點時,我們給它的failnode設定什麼呢?此時就要走該節點(h)的父節點(s)的失敗指標,一直回溯直

到找到某個節點的孩子節點也是當初節點同樣的字元(h),沒有找到的話,其失敗指標就指向root。

比如:h節點的父節點為s,s的failnode節點為root,走到root後繼續尋找子節點為h的節點,恰好我們找到了,(假如還是沒

有找到,則繼續走該節點的failnode,嘿嘿,是不是很像一種回溯查詢),此時就將 」she"中的「h」節點的fainode"指向

"her"中的「h」節點,好,原理其實就是這樣。(看看你的想法是不是跟圖一樣)

針對圖中紅線的」h,e「這兩個節點,我們想起了什麼呢?對」her「中的」e「來說,e到root距離的n個字元恰好與」she「中的e向上的n

個字元相等,我也非常類似於kmp中next函式,當字元失配時,next陣列中記錄著下一次匹配時模式串的起始位置。

動態模板:

char a[1000001],p[55];

struct trie

};trie *root,*s,*lrelia;

void create(char *str)

s=s->child[id];

i++;

}s->cnt++;

}void makefail() //乙個節點乙個節點找fail指標

temp = temp->fail ;//父結點向上轉移  

}  if(temp->fail == null)  

front->child[i]->fail = root ;  

}  q.push(front->child[i]) ;//找到孩子i的fail指標後將孩子i加入佇列  

}  }  

}  }

int search(char *str)

if(p->child[k] != null)  

}  i++;  

}  return ans;  

}靜態模板:

struct trie

void set()

}t[240005];

int p;

void create(char *s)

t[root].cnt++;

}void makefail() //構造fail指標

temp=t[temp].fail;

}if(t[temp].fail==-1) //fail當然有可能等於0咯

t[t[front].child[i]].fail=0;

}q.push(t[front].child[i]);}}

}}int search(char *s) //查詢字串

}i++;

}return ans;

}

AC自動機 建立nlogn個AC自動機

string set queries 題意 給你3種操作,1 加入乙個串到集合中。2 刪除集合中的某乙個串 3 查詢集合中的字串在給定的字串種出現幾次。同乙個串可重複 解法 建立多個ac自動機,用二進位制分組來處理。加入給你21個串 分為 16 4 1,再新增乙個串的時候,即21 1,22 16 4...

AC自動機的實現原理

最近學習ac自動機,看了不少講解ac自動機的文章,幾乎都是在講如何操作。估計不少人學習時像我一樣在想ac自動機演算法為什麼能實現多模式串匹配操作。如下是我的思考成果,如有漏洞,歡迎指正。建立trie樹比較容易,構造fail指標其實是同樣的匹配過程,只要理解query 也就都明白了,下面主要來說說qu...

AC自動機及字尾自動機

ac自動機是一種基於trie樹的演算法,其本質和kmp上的處理很相似。trie樹結構 kmp轉移思路 ac自動機組要由三個部分組成 trie樹的建立 fail指標的匹配 對ac自動機的詢問 每次建立自動機會有一次初始化 ac自動機類 struct node node結構體 struct ac voi...