題目:給乙個字串s和乙個字串陣列t(t中的字串要比s短許多),設計乙個演算法,在字串s中查詢t中的字串。
思路:字串的多模式匹配問題。
我們把s稱為目標串,t中的字串稱為模式串。設目標串s的長度為m,模式串的平均長度為 n,共有k個模式串。如果我們用kmp演算法(或bm演算法)去處理每個模式串,判斷模式串是否在目標串中出現,匹配乙個模式串和目標串的時間為o(m+n),所以總時間複雜度為:o(k(m+n))。一般實際應用中,目標串往往是一段文字,一篇文章,甚至是乙個基因庫,而模式串則是一些較短的字串,也就是m一般要遠大於n。這時候如果我們要匹配的模式串非常多(即k非常大),那麼我們使用上述演算法就會非常慢。這也是為什麼kmp或bm一般只用於單模式匹配,而不用於多模式匹配。
那麼有哪些演算法可以解決多模式匹配問題呢?貌似還挺多的,trie樹,ac自動機,wm演算法,字尾樹等等。我們先從簡單的trie樹入手來解決這個問題。
trie樹,又稱為字典樹,單詞查詢樹或字首樹,是一種用於快速檢索的多叉樹結構。比如英文本母的字典樹是乙個26叉樹,數字的字典樹是乙個10叉樹。
回到我們的題目,現在要在字串s中查詢t中的字串是否出現(或查詢它們出現的位置),這要怎麼和trie扯上關係呢?
我們發現,如果乙個串t是s的子串,那麼t一定是s某個字尾的字首。比如t = bc,那麼它是字尾bcd的字首;又比如說t = c,那麼它是字尾cd的字首。
因此,我們只需要將字串s的所有字尾構成一棵trie樹(字尾trie),然後查詢模式串是否在該trie樹中出現即可。如果模式串t的長度為n,那麼我們從根結點向下匹配,可以用o(n)的時間得出t是否為s的子串。
**:
#include #include using namespace std;
class trie;
trie::trie(const char* s)
}void trie::insert(const char* s)
p = trie[p][i];
++s;
}}bool trie::find(const char* s)
return true;
}int main();
int n = 5;
for(int i=0; i2 )的時間, (m為s的長度),及o(m2 )的空間。
AC自動機 trie樹實現高效多模式匹配字典
經常會遇到一類需求,在一段字串中查詢所有能匹配上的模式,比如查詢一段文字匹配上字典中哪些短語。這時為了高效處理,就會考慮 ac 自動機,即 aho corasick 自動機演算法。它的核心思想是通過有限自動機巧妙地將字元比較轉化為了狀態轉移。通過 ac 自動機能做到匹配時不需要回溯,而且時間複雜度為...
Trie樹應用 統計與匹配
trie樹,是一種樹形結構,是一種雜湊樹的變種。典型應用是用於統計,排序和儲存大量的字串 但不僅限於字串 所以經常被搜尋引擎系統用於文字詞頻統計。它的優點是 利用字串的公共字首來減少查詢時間,最大限度地減少無謂的字串比較,查詢效率比雜湊表高。trie樹的基本特徵 1 根節點不包含字元,除根節點外每乙...
精確多模式匹配問題 關鍵詞樹 字尾樹
一 多模式匹配問題 給定一組模式和乙個文字,在文字中查詢任一模式的全部出現資訊。輸入 k個模式的集合p1,p2,pk,以及文字t t1.tm 輸出 所有位置i 1 i m 的資訊,使得與模式pj 1 j k 相同的t的子字串從位置i開始 1 樹的每條邊都被字母表的乙個字母標記。2 從同一頂點延伸出的...