字尾陣列(倍增法)

2021-08-07 21:39:58 字數 849 閱讀 7840

字尾陣列(suffix array):將某個字串的所有字尾按字典序排序後得到的陣列。

演算法:樸素實現:直接將所有字尾進行排序,將n個長度為o(n)的字串進行排序,時間複雜度o(n^2*logn);倍增演算法:通過充分利用各個字尾之間的聯絡,將構造字尾陣列的最壞時間複雜度成功降至o(n*logn)。

倍增法實現:首先計算從每個位置開始的長度為1的子串的順序,再利用這個結果計算長度為2的子串的順序,接下來計算長度為4的子串的順序,不斷倍增,直到長度大於等於n就得到了字尾陣列。

下面,我們用sa[i]表示按字典序排序後第i小子串的開始位置;用s[sa[i],k]表示從位置sa[i]開始的長度為k的字串子串,其中,剩餘字元不足k個時,表示的是從sa[i]開始到字串末尾的子串;rank[sa[i]]為s[sa[i],k]在所有排好序的長度為k的子串中是第幾小的(核心:rank[sa[i]]=i,其中i代表第幾小)。

最後,從每個位置開始的排序部分,因為比較rank[sa[i]]和rank[sa[j]]就相當於比較s[sa[i],k]和s[sa[j],k],比較rank[sa[i]+k]和rank[sa[j]+k]就相當於比較s[i+k,k]和s[j+k,k](或s[i,2*k]和s[j,2*k])。所以,我們可以利用上一步的rank來高效地比較長度為2*k的子串,並將它們排序。

**:

int n,k;

int rank[max_n+1];

int tmp[max_n+1];

//比較(rank[i],rank[i+k])和(rank[j],rank[j+k])

bool cmp_sa(int i,int j)

{ if(rank[i]!=rank[j]) return rank[i]

字尾陣列倍增法

字尾陣列 字尾陣列是處理字串的有力工具。字尾陣列是字尾樹的乙個非常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也並不遜色,而且它比字尾樹所占用的記憶體空間小很多。可以說,在資訊學競賽中字尾陣列比字尾樹要更為實用。1.1 基本定義 子串 字串s的子串r i.j i j...

字尾陣列 倍增法詳解

主要是基於基數排序,如果基數排序沒弄懂 就會很難理解 首先從k 0開始,從字尾陣列裡面選取步長為2 k的字尾陣列的前子串 然後進行基數排序 如果排序後所有的名次陣列的值都不相同,那麼排序結束 否則,k 也就是步長翻倍 繼續排序。陣列sa sorted array 構造完成前表示關鍵字陣列,下標表示名...

字尾陣列 倍增演算法模板

關於字尾陣列的資料,可以看noi2009國家集訓隊 羅穗騫 的 字尾陣列 處理字串的有力工具 suffix array 倍增演算法 o n lgn build sa n 1,注意n 1 getheight n n 8 num 注意num陣列最後一位值為0,其它位須大於0 rank rank 0 n ...