字串匹配之後綴樹

2021-06-20 21:44:12 字數 997 閱讀 3940

試想有這樣乙個問題,有乙個長度為n的字串a(n值很大),還有乙個模式串b,b的長度為m(n/m很大,說明b只是乙個小片段),此時需要判斷b是否是a的字串。如果我們使用kmp演算法的話,那麼複雜度為o(n),對a串進行k次模式匹配的話就是ko(n),此時為了降低複雜度,我們可以考慮預處理長字串a,是的,如果我們預先處理好a的字尾樹,那麼搜尋子串的複雜度就降為o(m),進行k次匹配為ko(m),和原來相比,效率大大提高。那麼預處理字串a的複雜度為多少呢?使用ukkonen的演算法,它的時間和空間複雜度都為o(n),這就像是做了一件一勞永逸的事情一樣,一次預處理,多次使用。或許你已經猜到了,我描述的問題就是dna序列的匹配。

乙個長度為n的字串s,它的字尾樹是一棵滿足以下條件的樹:

每條邊都代表乙個非空字串;

所有的內部結點(根節點除外)都至少有2個子節點(資料壓縮

有n個葉子節點,且從根到葉子的路徑表示了乙個唯一的字尾(前提是字串s的最後一位字元時字典中唯一存在的,顯而易見s的不同字尾有n個)。

或許看定義不容易理解,那我們來舉個栗子。我們從suffix trie開始講。suffix trie 是一棵列出字串a所有字尾的樹。比如字串a=abaaba$

其實suffix trie和suffix tree僅僅差一步之遙。從圖中我們可以看到每一條邊僅表示乙個字元,這樣列出所有字尾需要的節點數為(1+2+...+n),空間複雜度為o(n2)。這樣對於長字串(比如基因序列),我們就不可忍了。仔細觀察字尾字典樹的結構,我們會發現很多路徑都沒有分支了,既然沒有分支,那麼我們就可以把它們集合在一起(資料壓縮),這樣每條路徑表示的就不是乙個字元了,而是乙個字串行,可以用字串中的索引值表示。

#翻譯# 介紹字尾樹(suffix tree)

字串演算法之後綴陣列

字串演算法一直是我最不願碰的東西,包括dp。ababs 中所有的字尾串為 ababs babs abs bs s 我們按照字典序排列即為 ababs abs babs bs s 而字尾陣列就是用來求字尾的字典序的 sa i 為排名為i的字尾第乙個字元在主串裡的位置.譬如上面的例子 sa 1 1,sa...

字典樹字串匹配

哦,不!你不小心把乙個長篇文章中的空格 標點都刪掉了,並且大寫也弄成了小寫。像句子 i reset the computer.it still didn t boot 已經變成了 iresetthecomputeritstilldidntboot 在處理標點符號和大小寫之前,你得先把它斷成詞語。當然...

字尾樹求最長子字串

問題描述 給定乙個文字檔案作為輸入,查詢其中的最長子字串。例如,ask not what your country can do for you,but what you can do for your country 中的 can do for you 就是最長子字串。解題過程 這個問題最直接的解...