這裡用的是kuangbin的ac自動機的板子。
ac自動機,怎麼說呢,其實就是trie樹(字典樹)加上kmp的演算法思路。
int createnode()
end[tot++]=0; //表示模式串的終端節點,用來標記某個模式串
return tot-1;
}void init()
void insert(char *str)
cur=next[cur][str[i]-'a'];
}end[cur]++;
}
這一段其實就是建立trie樹的**,不懂的話可以學一下。
其實就是用next二維陣列來模擬建樹。
接下來就是ac自動機的核心部分,fail指標的構建,
這裡的fail函式其實就是類似kmp演算法的next函式,如果我們的模式串在tire
上進行匹配時,與當前節點的關鍵字不能繼續匹配的時候,就應該去當前節點的
fail指標所指向的節點繼續進行匹配。
這裡盜用一些別人的配圖
例如模式串有,say,she,shr,her.
上圖就是根據這些模式串來建立trie樹,紅圈其實就是上述的end陣列,
表示這條路徑上到這個節點所組成的字串是模式串的其中乙個。
接下來我們就要根據這個圖還有**來建立fail指標。
**3-5行是處理模式串的第乙個字元,第一層的fali指標都是指向root節點的。
如圖,按照字典序,h的fail指標指向rt,如圖中的虛線1(虛線就是該節點fail指標的指向),
然後把h入隊,接著處理s.由於第一層,所以s的fail指標也是指向root節點,如圖中的虛線2,
然後把s入隊。佇列中就有(h,s).
第一層出現到這裡就結束的。
接著就出現佇列中的節點。首先是h,h的next節點有e,當for迴圈處理到e這個節點時,
那麼就進行19行~20行的操作,找e的fail指標,那我們就返回到第一層尋找有沒有
之前有沒有出現過e這個節點,發現沒有,那麼e這個節點的fail指標就指向root節點,
也就是圖中的虛線3,然後e入隊,這時候處理完h所以的next節點,佇列中現在有(s,e),
接著處理佇列中的s節點,s的next節點有a,h,a和上面的e是同理的,這裡就不說,
記得找到a的fail指標,要把a入隊哦。
接著處理h,我們發現上一層(也就是第一層)出現過h這個節點,那麼h的fail指標
就指向第一層的h節點,也就是虛線5,
然後h入隊,這時候佇列中有(e,a,h),其實接下來的步驟和上面是一樣的,依照
迴圈,最後找出所有節點的fail指標,
那麼ac自動機最核心的部分講完了。
接著就是模式串匹配了。
模式串:say,she,shr,her
主串:yasherhs
int query(char *buf)
}return res;
}
首先呢,y和a在trie樹沒有對應的路徑,不會執行while迴圈,所以直接跳過。
接著就s,h,e這三個了,由於s,sh這都不是模式串,所以res還是0,
當到e這個節點的時候,這時候cur是在she這條路徑的e節點上,恰好she是乙個模式串,
那麼res+=1,然後把end[temp]變成0是為了防止後面會出現同樣的模式串。
接著我們就跳到e的fail指標所指向的節點,我們會發現,當前節點也是模式串
的乙個,即he,那麼我們已經找到兩個模式串she,he了。
接著到r了,這時候的r的節點是在her這條路徑上的,剛好也就是
模式串的其中乙個,那麼res就+1.可能有小夥伴就會疑問了,你之前的路徑不是she
上的嗎,怎麼會跑到her這條路徑上呢。
其實這個在建立fail指標上就有了。
if(next[cur][i]==-1)
解釋就在這裡,剛好she這條路徑上的下乙個節點為-1(即e的下乙個節點並不是r),
那麼我們就會條到e的fail指標指向的節點上繼續匹配,正好he這條路徑上有r,
所以我們就匹配了模式串her了,是不是很巧妙,我也覺得很巧妙。
接著的h,s都找不到對應的模式串的,匹配結束,那麼res為3,匹配串分別是she,he,her.
匹配的過程有兩種:
(1)當前字元匹配,表示從當前節點沿著樹邊有一條路徑可以到達目標字元,此時只需沿該
路徑走向下乙個節點繼續匹配即可,目標字串指標移向下個字元繼續匹配;(2)當前字元
不匹配,則去當前節點失敗指標所指向的字元繼續匹配,匹配過程隨著指標指向root結束。
重複這2個過程中的任意乙個,直到模式串走到結尾為止。
大概ac自動機入門就是這樣子啦,如果有錯的地方,希望大家提出來,一定會改的。
AC自動機理解
對於ac自動機可能有的疑問。首先上 該 使用char型陣列儲存,事實上string也完全可以。includeusing namespace std char s 1000005 struct tree 字典樹 ac 1000000 trie樹 int cnt 0 trie的指標 inline voi...
AC自動機的一點理解
fail 指標 指向最長的在 tire 裡出現的字尾 比 tire 多出來的子邊 原來的 tire 我們失配後又得返回根結點再次匹配,而加入這些邊後只需要花 strlen s 就能實現所有匹配 跑 tire 圖 能跑到乙個結點,該結點所代表的串能被文字串表示 問題1 多個模式串,乙個文字串,有幾個模...
暖 墟 AC自動機 AC自動機的總結與運用
kmp 匹配單串,線性掃瞄,在失配時用next陣列引導j指標回溯,進行下一步匹配。trie樹 多模式的匹配,構造26叉樹,同時記錄多個串的情況,記錄結尾,進行匹配。kmp trie樹 ac自動機 ac自動機 給乙個字典,再給乙個文字,問這個文字裡出現了字典裡的哪些字。可以用n個單詞的n次kmp演算法...