字尾陣列理解

2021-07-24 17:43:02 字數 1699 閱讀 9374

參考pdf

cnblog

gitbook

計數排序和基數排序都用到了

第一步和每次求sa都用到了

基數是在第一關鍵字和第二關鍵字時用到

for(p=0,i=n-j;i=j) y[p++]=sa[i]-j;

y的內容是按照第二關鍵字排序結果(內容是下標),第一句是因為小於長度的沒有第一關鍵字

,所以排序結果在最前面。第二句其實和rank差不多,只不過前幾個已經被佔了。

for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];需要理解y中的內容

x儲存的是rank

y儲存的是下標

因為排序會出現sa相同,所以儲存rank的x會有相同的情況

int wa[maxn],wb[maxn],wv[maxn],ws[maxn];

inline

bool cmp(int *r,int a,int b,int len)

void sa(char *r,int *sa,int n,int m)

//對第一關鍵字基數排序。

for(i=0;i0;//清零。

for(i=0;i//第二關鍵字排在第i個的起點在y[i],x[y[i]]就是y[i]指向的字元,ws進行個數統計。

for(i=1;i1];//統計字元小於等於i的個數。

for(i=n-1;i>=0;i--)//wv[i]是排在第i個第二關鍵字對應的第一關鍵字。

sa[--ws[wv[i]]]=y[i];//y[i]就是第一關鍵字的位置。

for(t=x,x=y,y=t,x[sa[0]]=0,p=i=1;i//交換x,y的位址,x儲存當前rank值,y為前一次rank值。

x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;

//若rank[sa[i-1]]=rank[sa[i]],則必然sa[i-1]+j沒有越界,因為不可能有相等的字尾。

}}

height陣列:height[i]=suffix(sa[i-1])和suffix(sa[i])的最長公共字首,也就是排名相鄰的兩個字尾的最長公共字首。

h陣列:h[i]=height[rank[i]]=suffix(i)和在它前一名的字尾的最長公共字首。

證明:設suffix(k)是排在suffix(i-1)前一名的字尾,則它們的最長公共字首就是h[i-1]。那麼suffix(k+1)將排在suffix(i)的前面。

a、若suffix(k)與suffix(i-1)的最長公共字首<=1,即h[i-1]<=1,h[i]>=0顯然成立。

b、若suffix(k)與suffix(i-1)的最長公共字首》=2,suffix(k)與suffix(i-1)同時去掉首字元得到suffix(k+1)與suffix(i),則suffix(k+1)排在suffix(i)的前面,且suffix(k+1)與suffix(i)的最長公共字首=h[i-1]-1。設suffix(t)是排在suffix(i)前一名的字尾,則它們的最長公共字首就是h[i],那麼suffix(t)=suffix(k+1)或者suffix(t)排在suffix(k+1)前面,則h[i]>=h[i-1]-1。

int rank[maxn],height[maxn];

void height(int *r,int *sa,int n)

字尾陣列模板(詳細理解)

字尾陣列看了很久了,從基數排序開始看乙隻看到height陣列的實現也理解了很多東西,不過別人的東西再多也不是自己的,因此自己重新總結了一下,順便學乙個字尾陣列的模板備用,這裡以spoj 694為例。include include include include include using names...

字尾陣列倍增法理解

int wa maxn wb maxn wv maxn ws maxn int cmp int r int a,int b,int l void da int r int sa int n,int m 字尾陣列最終得到的是sa和rank兩個陣列,sa i 是排第i名的是誰,rank i 是以第i個字...

字尾陣列的理解於模板

字尾陣列主要是得出 sa i pos 排名第i的是pos位置開始的 這裡用於排名的都是原串中以不同位置開始到最後的字串按照字典序排序 height i 是 suffix sa i 1 和 suffix sa i 的最長公共字首長度,即排名相鄰的兩個字尾的最長公共字首長度。原理可以參考 解釋 incl...