字尾陣列倍增演算法模板詳解

2021-08-08 06:50:57 字數 1628 閱讀 4178

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 :原字串中最大的字元值

for (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;

wt

陣列完成計數排序的功能。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 ,即對應段字串的排名)

for (i = 0; i < n; ++i) rk[sa[i]] = i;

int k = 0;

for (i = 0; i < n - 1; h[rk[i++]] = k)

求 he

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...