我的水平所限,只能談及幾年前的OI省選水平的算法。再高深的,便不清楚了。html
主要參考文獻:git
OI算法,大抵可分爲如下幾類:github
下面依次談一談。算法
這個算法是怎麼來的,是爲了解決什麼問題而來,之前的算法爲何沒有解決,而如今的算法卻能解決;如今這個算法還有些什麼缺點;能作一些什麼問題,不能作些什麼問題。—— Ronghua Li數組
KMP:在主串S(長度N)中匹配一個模式串P(長度M),預處理時間 O(M) ,匹配時間 O(N+M) 。數據結構
KMP及相關算法時間複雜度比較:函數
其中,M爲模式串長度,N爲主串長度。 實測時,string長度10000,每一個函數都被調用了1000次。
算法 | 預處理時間 | 匹配時間 | 實測時間 |
---|---|---|---|
BF | O(0) | O(NM) | 0.078 |
KMP | O(M) | O(N) | 0.094 |
BM | O(N+M2) | O(N) | 0.047 |
Sunday | O(M) | O(NM) | 0.172 |
Robin-Karp | O(0) | O(NM) | 0.328 |
Bitap | O(M) | O(NM)→O(N) | 0.281 |
Trie是一種n叉樹,n爲字母表大小,每一個節點表示從根節點到此節點所通過的全部字符組成的字符串。工具
AC自動機就是KMP思想。但用KMP作多模式串匹配的時間複雜度是 O(∑N+Mi) 。顯然,提升的複雜度是 O(N(K−1)) ,其中K表示模式串的個數。而當模式串數量大、模式串較短、主串較長時,算法幾乎是從 O(N2) 降到了 O(N) 。ui
還有一種多模式的匹配算法叫作AC自動機。它能一次匹配多個模式串。它與KMP的思路很像,不匹配時找一個最長的再繼續進行!它須要先把字符串建成一顆Trie樹,樹結點有一個叫作failed的指針,是表示若是不匹配時應該再從哪一個結點進行匹配。由於這種作法是一種DFA上的匹配,而發明這種算法的人叫A.C.,因此就叫AC自動機了。複雜度很好,比每一個模式串用一次KMP算法要好不少。atom
還有一種叫作後綴數組和後綴樹的,後綴樹是能夠轉發爲後綴數組的,這兩種構造起來很不簡單,可是複雜度倒是驚人的好。如求最長重複連續子串,出現次數最多的子串等都能用它完美的解決。有興趣的能夠搜搜,後綴數組的資料應該是比較多的,然後綴樹因爲太複雜,資料不是不少,仍是有的。
關於後綴數組構造的倍增算法,有一個特別好玩的小故事,你們能夠去看看~
《後綴樹,後綴數組,離散化》,去看73到81頁,可愛的小白兔們^_^
上面介紹的都是精確匹配的算法,其實對於字符串,還有一種模糊匹配,有興趣的讀者能夠閱讀一本叫作《柔性字符串匹配》的書,確定會讓你獲益匪淺。