圖解后綴樹,翻譯了3個小時,你還不懂的話,找我


看過非常多的不靠譜suffix tree介紹后,本文是我在網上發現至今最好的一篇,通過三個規則講述了整棵后綴樹的構建過程,圖形結合,非常容易理解,並且本文尊重原作者Ukkonen的論文術語,清楚的講解了出現在suffix tree中的每一個概念,花時3個小時翻譯之,共勉,部分有修改和拋棄。

正文如下:

接下來我將通過一個簡單的字符串(不包含重復的字符)來試着分析Ukkonen算法,接着來講述完整的算法框架。

首先,一點簡單的事前描述

1. 我們構建的是一個簡單的類似搜索字典類(search trie)結構,所以存在一個根節點(root node)。樹的邊(edges)指向一個新的節點,直到葉節點。

2. 但是,不同於搜索字典類(search trie),邊標簽(edge label)不是單個字符,相反,每一個邊被標記為一對整數[from, to]。這一對整數是輸入字符串的索引(index)。這樣,每一個邊記錄了任意長度的子字符(substring),但是只需要O(1)空間復雜度(一對整數索引)。

基本約定

下面我將用一個沒有重復字符的字符串來說明如何創建一顆后綴樹(suffix tree):

abc

本算法將從字符串的左邊向右邊一步一步的執行。每一步處理輸入字符串的一個字符,並且每一步抑或涉及不止一種的操作,但是所有的操作數和是O(n)時間復雜度的。

好,我們現在將字符串左邊的a插入到后綴樹,並且將此邊標記為[0, #],它的意思是此邊代表了從索引0開始,在#索引結束的子字符串(我使用符號#表示當前結束索引,現在的值是1,恰好在a位置后面)。

所以,我們有初始化后的后綴樹:

其意思是:

現在我們處理索引2,字符b。我們每步的目的是將所有后綴(suffixes)的結束索引更新當前的索引。我們可以這樣做:

1. 拓展存在的a邊,使其成為ab;

2. 為b插入一條新邊。

然后變成這樣:

其意思是:

我們觀察到了二點:

  1. 表示ab的邊同我們初始化的后綴樹:[0, #]。它意味着將會自動改變,我們僅僅更新#,使其成為2即可;
  2. 每一步只需要O(1)的空間復雜度,因為我們只記錄了一對整數索引而已。

接下來,我們繼續自增#索引,現在我們需要插入字符c了。我們將c插入到后綴樹中的每一條邊,然后在為后綴c插入一條新邊。

它們像下面:

其意思是:

我們注意到:

  1.  在每一步后,恰好都是一顆正確的后綴樹;
  2. 總共需要字符串長度的數量的操作;
  3. 所有的操作都是O(1)。

第一次拓展:簡單的重復字符串

上面的算法工作的非常正確,接下來我們來看看更加復雜的字符串:

abcabxabcd

步驟1至3:正如之前的例子:

繼續閱讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM