字尾陣列入門學習(1) 倍增演算法基礎

2022-03-27 03:10:25 字數 1137 閱讀 5186

滿心歡喜來了字尾陣列,但是發現自己很懵……

字尾陣列倍增演算法的板子並不長,但理解起來相對很困難。

字尾的含義自然不用說了……為了簡潔,我們設字尾i為從第i位開始的字尾。

需要這樣幾個陣列:

char s,存字串(廢話),int sa(本體),xx(中轉陣列,存rank),yy(中轉陣列,存編號),c(基排用)

然後我們需要預備知識:基數排序

形象一點:找了一堆桶,把每個數/字元放在對應的桶裡,然後按桶的編號挨個取出來,排好,就是基數排序。

在**實現上c陣列就是我們的桶,c[i]表示「字元值小於等於i的字元個數」

而對於字元值恰好等於i的那個字元,它的排名就是c[i](由於它是小於等於i的最大乙個字元),然後我們把c[i]-=1即可

**長這樣:

1 memset(c,0,sizeof

(c));

2for(int i=0;i//

這裡是一開始初始化賦值的地方

3for(int i=1;i1];4

for(int i=n-1;~i;i--)sa[--c[x[i]]]=i;

接下來,我們就可以介紹本體**了:

首先,我們對每個字元排序,這樣我們會得到每個字元的排名。可能有同學有疑問,按照基排的話,相同字母的排名就不同了怎麼辦?後面我們還會有去重的部分,所以我們中轉陣列這樣不重複的打也沒事。在這之後,我們給每個字尾的前兩個字元排序(沒有第二個字元的按照0處理,0最小,以後也是這樣操作)。這相當於給一些二元組排序。利用我們剛剛第一次給字母排序的結果,很容易實現這次排序(我們在從第二次開始每次排序後面都會進行一次去重)。

這之後,我們對每個字尾的前4個字元排序。由於對於字尾i和字尾j,給他們的前4個字元排序相當於「比較i和j的前兩個字元」和「比較i+2和j+2的前兩個字元」,而我們已經給前兩個字元排好序,所以這樣就可以利用前面排序的結果來操作。

不斷這樣操作,當每個字尾的排名都不同時,就可以跳出了。

**見下:

1

char

s[n];

2int

sa[n],rank[n],xx[n],yy[n],c[n],n;

3 inline void get_sa(int

m)//m為最大的字元值

424 }

學習筆記 字尾陣列 1

目錄 全文1820詞,預計閱讀時間5min 字尾陣列是處理字串的有力工具,常在比賽中用到。本文主要介紹字尾陣列的概念與部分例題。關於部分例題,我們將在後續文章介紹。那麼,我們可以先按第二關鍵字排序,此時序列是按照第二關鍵字從小到大排列的。我們再從左到右,按第一關鍵字排序。這樣就可以使得其有序。這就是...

學習筆記 字尾陣列 1

全文1820詞,預計閱讀時間5min 目錄例題 字尾陣列是處理字串的有力工具,常在比賽中用到。本文主要介紹字尾陣列的概念與部分例題。關於部分例題,我們將在後續文章介紹。那麼,我們可以先按第二關鍵字排序,此時序列是按照第二關鍵字從小到大排列的。我們再從左到右,按第一關鍵字排序。這樣就可以使得其有序。這...

字尾陣列入門

字尾陣列 suffix array 指某個字串的所有字尾按字典排序後得到的陣列。陣列中只儲存字尾開始的位置。簡稱sa。字尾 從某個字串的某個開始位置到其末尾的字串子串,包括原串和空字串。例子 的字尾,字典排序 預設從小到大 開始以長度為1的字尾字串為排序規則對其sa進行排序,並求出其排名rank 藍...