2009國家集訓隊** 字尾陣列——處理字串的有力工具 ——羅穗騫
請在理解了演算法的基礎上食用bool cmp(int* r, int a, int b, int l)
void init(int* r, int* sa, int n, int m)
for (i = 0; i < n; ++i) rk[sa[i]] = i;
int k = 0;
for (i = 0; i < n - 1; h[rk[i++]] = k)
}
void init(int* r, int* sa, int n, int m);
r :原字串sa
:字尾陣列,sa
[i]=
j 的含義是 ra
nk[s
uffi
x(j)
]=i ,即字尾 [j
,n−1
] 的排名是
i ,亦即排名第
i的字串的開頭位置是 j
n:原字串的長度,保證 r[
n−1]
=0
m :原字串中最大的字元值
wtfor (i = 0; i
< m; ++i) wt[i] = 0;
for (i = 0; i
< n; ++i) ++wt[x[i] = r[i]];
for (i = 1; i
< m; ++i) wt[i] += wt[i - 1];
for (i = n-1; i >= 0; --i) sa[--wt[x[i]]] = i;
陣列完成計數排序的功能。x[
] 陣列和後面的用法統一,x[
i]記錄以
i 開頭,長度為
j的字串的排名。在這裡,長度
j 為
1,故排名可以直接由 r[
] 等價而來。sa
陣列含義見上,sa
[i] 記錄排名第
i 名字串的開頭位置,在計算過程中,排名是針對 [i
,i+j
−1]一段而言的。x[
] 與 sa
互為逆運算。
只需比較第一關鍵字和第二關鍵字即可。(注意,這裡的for (j = 1, p = 1; p < n; j
<<= 1, m = p)
r 不是初始字串,傳進去的引數事實上是
y,也即原來的
x ,即對應段字串的排名)
求 hefor (i = 0; i < n; ++i) rk[sa[i]] = i;
int k = 0;
for (i = 0; i < n - 1; h[rk[i++]] = k)
ight
值,利用性質 h[
i]≥h
[i−1
]−1 ,**中的 h[
] 即為 he
ight
,k即為 h[
]
字尾陣列 倍增演算法模板
關於字尾陣列的資料,可以看noi2009國家集訓隊 羅穗騫 的 字尾陣列 處理字串的有力工具 suffix array 倍增演算法 o n lgn build sa n 1,注意n 1 getheight n n 8 num 注意num陣列最後一位值為0,其它位須大於0 rank rank 0 n ...
字尾陣列 倍增法詳解
主要是基於基數排序,如果基數排序沒弄懂 就會很難理解 首先從k 0開始,從字尾陣列裡面選取步長為2 k的字尾陣列的前子串 然後進行基數排序 如果排序後所有的名次陣列的值都不相同,那麼排序結束 否則,k 也就是步長翻倍 繼續排序。陣列sa sorted array 構造完成前表示關鍵字陣列,下標表示名...
字尾陣列模板詳解。
給定乙個字串s,比如它是 abcad 那麼它的字尾有 abcad bcad cad ad d 講這些字尾字串按照字典序排序,得到的就是字尾陣列。如果用普通的排序方法,排序要o nlogn 但是每兩個字元比較大小要o n 所以是o n n log n 的複雜度。但是利用特殊的演算法可以將其降到o nl...