以前還真認為ac自動機就是自動ac機
ac自動機,就是說,多模式匹配串,更像是一種樹上kmp,在學這個之前有一些前置技能:kmp,字典樹。
想學ac自動機,字典樹是必須要會的,因為它就是在字典樹上進行操作,但是它比字典樹多了乙個失配指標(fail指標)。本來我們要對一些的串進行匹配,那麼我們暴力要乙個乙個去匹配,每個串都要從頭開始匹配,那樣的話,太浪費時間了,但是加上了fail指標之後,就直接開始一遍過就可以匹配所有的模式串(其實我感覺,ac自動機的fail指標就像是kmp的next陣列在當前演算法一樣的重要地位)理解了fail指標,ac自動機也就理解了。
ac自動機三步走
1.用字典樹建圖,對模式串建圖,用字典樹把模式串全部存起來。
2.構建圖中的fail指標。
1).用bfs進行進行層次遍歷,先把root節點壓入佇列。(root的節點的fail為0)
2).對佇列裡面的結點進行出隊操作,然後以次遍歷這一層26個字母,如果有在樹上的,那麼我們通過它的父親的fail節點,來判斷當前節點的fail指標。
如果它的父親節點的fail指標指向root節點,那麼兒子的fail指標也將指向根節點。
如果它的父親節點fail指標不為0,那麼就找它指向的那個節點,判斷它的樹下有沒有當前節點的字母存在,存在的話,當前節點的fail指標就指向這個字母的編號,不存在就一直向上找,一直找到存在的或者root節點,然後退出迴圈。
3).壓入佇列。
4).若不存在這個字母節點,那麼主串就直接跟著父節點的fail指標往下繼續找。
3.主串查詢操作
1).按串開始按位遍歷。
2).每找到乙個數,先判斷這個數是否存在,要麼是root節點,不然就跟著fail指標往上找。
3).找到符合要求的之後,判斷當前節點是否作為單詞的根節點,有的話則num+=tree[x].numm(當前這個節點的有多少個單詞以此結尾)。
hdu—2222 題目傳送門
題目大意
給你n個字串,讓再給你一條很長的主串,問這n個字串中有多少個在這個主串裡出現過。
思路
ac自動機入門模板題,
#include
#include
#include
#include
#include
using
namespace std;
const
int n=
1e6+10;
struct zxc
tree[
3*n]
;char sl[
3*n]
;char s[55]
;int num;
void
init
(int x)
tree[x]
.fail=-1
; tree[x]
.cz=0;
}void
build
(char z)
else
} tree[u]
.cz++;}
void
acmadefail()
else
p=tree[p]
.fail;}if
(p<0)
} q.
push
(v);
}else}}
}int
acslary()
i++;}
return num;
}int n;
intmain()
scanf
("%s"
,sl)
;acmadefail()
;printf
("%d\n"
,acslary()
);}return0;
}
ac自動機模版hdu2222
剛開始想當然的以為是求單詞們出現了多少次,事實上是有多少單詞出現了 其實,理解了,寫這個不難 三步走1 加單詞建trie 2 get fail和 last陣列 3 套文字開始查詢,延失配邊走即可 include include include include include includeusing...
AC自動機初學(模板) HDU 2222
ac自動機這個東西,聽起來很高大上,在高中的時候不知道什麼是自動機,以為寫出了ac自動機就可以自動ac 現在知道了它是用來解決字串匹配問題的東西,說白了就是kmp trie。這個在去年暑假的時候,hc學長也略微提到過,但是沒有具體的講。在解決只有乙個模式串的匹配問題的時候,我們用樸素的kmp演算法即...
AC自動機詳解 入門模板 HDU 2222
第一次寫ac自動機,發現也不是太難理解,可能自己以前看過kmp trie而且理解的比較透徹吧,看自動機沒有太大的困難,因為它也是利用了kmp的思想,理解了kmp,再看自動機就不難了 轉一下這個blog的描述先,感覺看起來比較好理解,可是他的 就不敢恭維。有改動 補充一句 自動機的複雜度是o m n ...