字尾陣列sa是乙個一維陣列,它是將 s 的 n 個字尾從小到大進行排序之後把排好序的字尾的開頭位置順次放入 sa 中。比如:banana的所有字尾是banana,anana,nana,ana,na,a,按照字典序排列就是a,ana,anana,banana,na,nana,那麼字尾陣列就是。
首先將單個字元排序,計算出每個字母的名詞。
然後給所有字尾的前兩個字元排序,這等價與給一些二元組排序,其中每個二元組就是乙個字尾的前兩個字元的名次。
接下來,是給每個字尾的前四個字元排序,注意,這次排序的物件仍然是二元組,注意到每個字尾k的前四個字元是由字尾k的前兩個字元和字尾k+2的前兩個字元組成,如果字尾k與k`相比,那麼首先應該比較它們的前兩個字元。
當所有名次已經兩兩不同,演算法結束。
注意到字元種類最多m種,所以可以採用基數排序,演算法每一輪的時間複雜度降為o(n),總的時間複雜度為o(nlogn)。
void build_sa(int *r, int n, int m)
} int cmp(int *r,int a,int b,int l)
只有sa陣列可以做的事情並不多,我們還需要兩個輔助陣列rank,height。rank[i]代表字尾i在sa陣列中的下標。height[i]代表sa[i-1]和sa[i]的最長公共字首長度。對於兩個字尾j,k,不難證明j和k的lcp長度等於height[rank[j]+1],height[rank[j]+2],......,height[rank[k]]中的最小值,即rmq(height, rank[j]+1, rank[k])。o(n)時間計算height需要乙個輔助陣列h[i] = height[rank[i]],然後遞推。遞推的關鍵是:h[i] >= h[i-1]-1。
void calheight(int *r, int n){
int i, j, k=0;
for(i=1; i<=n; i++)
rank[sa[i]] = i;
for(int i=0; i
字尾陣列學習
參考 演算法入門經典 和rank 名次陣列 字尾i在所有字尾中從小到大排列的名次 以第k個字元開始的字尾稱為字尾k rank 0 n 1 有效 height height i suffix sa i 1 和suffix sa i 的最長公共字首,也就是排名相鄰的兩個字尾的最長公共字首。height ...
字尾陣列學習小結
這兩天學習了字尾陣列,感想是,果然字尾陣列比網路流可愛的多,就像字串比圖論可愛的多。有模板真好qvq。總結了一下字尾陣列的幾個要點 一.理解rank sa height三個陣列。分別代表所構成的字尾陣列str i 在程式裡並不表現出來 排名後的名次 排名後第i位是str中的哪乙個 str sa i ...
字尾陣列學習 模板
字尾陣列學習 模板 裡面說的很清楚,各個變數的解釋還蠻清晰 該鏈結裡面有很多文章,這篇有圖形解釋,容易理解 不過有書看也更好 字尾陣列的思想 先比較所有字尾的 前2 0次方個字元,然後比較 前2 1次方個字元,然後 2 2,2 3,直到所有字尾的 前2 i 個字元比較不存在完全相同的情況,就停止。1...