1. 程式人生 > >字尾陣列學習筆記 (轉)

字尾陣列學習筆記 (轉)

字尾陣列學習筆記

轉載來源:https://www.cnblogs.com/Mychael/p/8282898.html

字尾陣列,顧名思義,一定與字尾有關。字尾陣列簡稱sa,sa[i]表示在字串s的所有後綴中,排名第i的字尾的首字母在字串中的位置。【排名從0開始】
比如,對於字串"ababa",排名第一的字尾是最後一個a,那麼sa[0]=4.

我們要做的事情,就是求出這個陣列,怎麼求呢?
觀察下面這張圖片
就像一個兩位數的比較
利用倍增的思想,我們先按每個字尾的第一個字元排序,再按每個字尾的前2個字元排序,再按每個字尾的前4個字元排序......直到沒有相同排名為止

具體排序如何實現?
利用之前的排序,4個字元的排序其實可以轉化為兩個2個字元的排序,任意一次排序都是一個雙關鍵字排序。
我們就可以利用基數排序很快的進行排序。

什麼是基數排序?
基數排序遵循這樣一個事實:按關鍵字對排序結果的的決定性從弱到強進行排序,最後的結果一定符合排序要求。
然後我們拿一個桶,裝下出現的每一種數,然後再利用桶的字首和來求出每個位的排序
舉個例子:
3 4 6 82 99
我們知道,數字排序可以看作多個關鍵字排序:個位、十位、百位、千位......其中越高位決定性越強。
於是我們從個位開始排序【由於每個數都是0~9之間的,所以我們只需要十個桶】:

每個桶表示這個數字有多少個,到最後結果應該是這樣的:
    0 0 1 1 1 0 1 0 0 1
 [  0 1 2 3 4 5 6 7 8 9  ]
然後我們求出字首和,表示不大於這個數的數有多少個
0 0 1 2 3 3 4 4 4 5
利用字首和,我們就能很快得到排序




利用基數排序,我們就可以實現字尾陣列啦: