AC自動機 學習筆記

AC自動機??!!

AhoCorasickautomaton ,該算法在1975年產生于貝爾實驗室,是著名的多模匹配算法。
什麼是多模匹配?
就是給你一段m 個句子的集合S ,給出n 個單詞,查看這些單詞是否在S 中出現過;

AC自動機

AC 自動機之前,一定要看看TireKMP
因爲AC 自動機就相當於在Tire 樹上進行KMP
AC 有一種類似於KMPnext[] (不要寫next ,c++11CE 的….)的東西叫fail 指針
fail 指針的功能:當你匹配失敗的時候,你可以調到當前節點的fail 指針所指的節點繼續匹配.
所以:
AC 的構建過程:
1. 先把所給的串插入Tire
2. 然後構建fail 指針
3. 就可以匹配了
下面就是一個已經構造完成fail 指針的AC
紅邊爲fail 指針
這裏寫圖片描述
fail 指針是怎樣構建的呢?
用一句話簡單的說就是,假如你要構建now 節點的失配指針,假如它的父節點的失配指針指向的節點有一條和now 節點到它父親的邊一樣的邊,那麼now 節點的失配指針指向這一條邊所指向的節點.

代碼

代碼就比較好理解了,

inline void Build(char s[])
{
    int l=strlen(s);
    int now=0;
    for(int i=0;i<l;++i)
    {
        if(AC[now].vis[s[i]-'a']==0)
        AC[now].vis[s[i]-'a']=++cnt;
        now=AC[now].vis[s[i]-'a'];
    }
    AC[now].end+=1;
}
void Get_fail()
{
    queue<int> que; 
    for(int i=0;i<26;++i)
    {
        if(AC[0].vis[i]!=0)
        {
            AC[AC[0].vis[i]].fail=0;
            que.push(AC[0].vis[i]);
        }
    }
    while(!que.empty())
    {
        int u=que.front(); que.pop();
        for(int i=0;i<26;++i)
        {
            if(AC[u].vis[i]!=0)
            {
                AC[AC[u].vis[i]].fail=AC[AC[u].fail].vis[i];
                Q.push(AC[u].vis[i]); 
            }
            else 
                AC[u].vis[i]=AC[AC[u].fail].vis[i];
        }
    }
}

如果有不正確的地方可以指出來,謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章