算法分析與設計(後綴樹)

一、後綴樹的定義:通過一個樹可以表示所有可能的後綴子串;

例子:S=acacag;

1)每一條邊用一個字符串標記;2)所有的後綴可以從根結點到所有葉結點的路徑讀出;

3)結束標記符“$”(避免某些後綴是其他後綴的前驅);

後綴樹的特點:1)長度爲n的字符串,其後綴樹恰好有n個葉子結點(因爲有n個後綴);

2)每一條邊可以用個數據表示(在原來字符串的起始位置和結束位置);

3)在一個後綴樹中至多有2n-1個結點;

證明:首先已知有n個葉子結點其度數爲0,除了根結點和葉子結點每一個內部結點
的度數爲2,根結點度數不定設爲x,x的取值範圍爲【2,n0】
在這裏設葉子結點爲n0,度數爲2的結點爲n2,總結點個數爲n
易得:n=n0+n2+1;//這裏的1爲根結點
由度數的關係可得出:2*n2+x+1=n;//葉結點不提供分支,根結點提供x個分支,其餘結點提供2個分支
聯立上述兩式子可得出:n=2n0+1-x;即可得出節點總數n的取值範圍爲【n0+1,2n0-1】

4)一個後綴樹可以用O(nlogn)位表示;

二、後綴樹的簡單應用

1)在S中找出所有的出現Q的子串個數:從根結點出發,沿着唯一的路徑Q到達點x,所有x以下的葉子結點均爲出現過Q的子串

時間複雜度爲O(|Q|+出現次數)總體上呈現線性級; 

2)找出S中的最長重複子串:找出具有最大深度的內結點,其所對應的路徑即爲最長重複子串

時間複雜度爲O(n) 

3)求解不同序列的最長公共子序列:將不同序列S全部構建在一個後綴樹中,每個葉子結點用不同的結點加以標記,找出

具有最大深度的內部結點且此結點同時包含不同串的後綴;

除此之外還有其他應用:如最長匹配 、最大回文、最長公共前驅等等;(算法的時間複雜度爲O(n))

三、後綴樹構造算法(複雜度O(n^2))

1)首先初始化一個樹只有一個根結點;O(1)

2)之後循環遍歷n次,將各個後綴子串加入到這棵樹中;O(n^2)

四、隱含後綴樹(方法):1)將所有的邊中的$全部刪除;2)去除所有沒有標記的邊;3)刪除只有一個孩子的結點;

(如圖所示:隱含後綴樹中沒有結束標記符,且每個內部結點的孩子個數大於等於2,邊值用於保存路徑信息)

隱含後綴樹

Rule1:如果在樹中發現與當前匹配S【j,i】的路徑且終止於一個葉子結點,即將S【i+1】加入這條邊的末尾即可;

Rule2:如果在樹中發現與當前匹配S【j,i】的路徑但其後面的元素不是S【i+1】建立一個新的葉子結點,以及一個

新的內部結點,新舊結點的邊標記爲S【i+1】,這個新的葉結點標記爲i;

Rule3:如果從根節點開始的標記爲S【j,i】的路徑終止於非葉節點邊(即在該路徑上S[i]字符後還有其他字符)而且

下一個字符是S【i+1】(樹中已經存在),那麼什麼也不做。

隱含後綴樹的構造,以S=acca爲例子(illustration):

Step1:i=1時,根據規則1可知直接創建一個葉子結點1將邊標記爲a即可;

Step2:i=2時,對於S=ac,根據規則1將c加入1葉子結點的上部;對於S=c,根據規則2創建一個葉子結點2將邊標記爲c即可;

Step3:i=3時,對於S=acc,根據規則1將c加入1葉子結點的上部;對於S=cc,根據規則1將c加入2葉子結點的上部;

對於S=c,根據規則3不做任何處理;

Step4:i=4時,對於S=acca,根據規則1將a加入1葉子結點的上部;對於S=cca,根據規則1將a加入2葉子結點的上部;

對於S=ca,根據規則2將健一個新的葉子結點3和一個內部結點(邊值爲a);對於S=c,根據規則3不做任何處理;

(下圖爲T3變換爲T4的後綴樹構建,也就是STEP4所解釋的)

說的簡單一點就是每一次添加新的後綴前先判斷這個後綴在樹中是否存在如果不存在則直接創建,如果存在根據其後面的

元素來進行對應的操作1)到達葉子時:直接插入到葉邊;2)未到達葉子:創建一個新的葉子結點邊標記爲S【i+1】 與內

部結點相連;

構建算法:(1、初始化一棵樹;2、循環遍歷n-1次將樹從Ti變換到Ti+1,對於內層循環逐漸更新後綴樹通過β=S【j,i】路徑

來根據三種規則將S【i+1】添加至樹中)

內外層循環時間複雜度爲O(n^2),對於每一次的擴展找β的位置時間複雜度爲O(|β|),所以總體的時間複雜度爲O(n^3);

觀察1:規則3一旦使用,其後面的操作均可以省略(減少執行次數,是一個停止規則

證明:當我們用Rule3擴展β=S【j,i】時,在樹中一定存在一個路徑以S【i+1】結束路徑;所以對於其後面的路徑

也一定有以S【i+1】結束路徑;(使用Rule3 break即可)

換一種說法就是β=S【j,i】的後綴一定在這顆樹中所以一旦在S【j,i】中Rule3那麼其其它的後綴也一定滿足此條件;

觀察2:葉子一旦被創建就不會改變(不會被刪除或修改);(一日爲葉子終身爲葉子

技巧:對於任意一顆隱含後綴樹,其內部結點除了根結點都有一個後綴鏈;

對於一個內部結點v其路徑標籤爲xα,如果存在其他結點s(v)其路徑標籤爲α,稱v指向s(v)的鏈爲後綴鏈(suffix link)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章