字尾陣列入門

2022-02-06 05:52:12 字數 1770 閱讀 8518

字尾陣列 (suffix array)指某個字串的所有字尾按字典排序後得到的陣列。陣列中只儲存字尾開始的位置。簡稱sa。

字尾:從某個字串的某個開始位置到其末尾的字串子串,包括原串和空字串。

例子:的字尾,,,{}

字典排序: 預設從小到大

開始以長度為1的字尾字串為排序規則對其sa進行排序,並求出其排名rank(藍色區域)

以長度k的字尾字串的rank為排序規則對sa排序,求出長度為2k的字尾字串的排序結果.並求出長度為2k的rank.原因:長度為2k的字尾字串的rank總能由長度為k的字尾字串的rank求出(綠色區域->綠色區域)

重複步驟2 直到構造出完整的sa。

(圖:以之前的rank構造新的rank的過程)

下面給出用未優化後的**。

未優化**(點選展開)

#include #include #include #define maxn 1000

using namespace std;

char str[maxn];//字串陣列

int sa[maxn + 1];//字尾陣列,+1是為了儲存(空字串)

int rank[maxn + 1];//rank[i]第i位開始的子串排名(0~n)

int tmp[maxn+1];

int k,n;

bool cmp_sa(const int &i,const int &j) 通過lsd基數排序變為

這只是lsd基數排序的原理而已。

要將基數排序運用到字串上還需要一些小改變。具體可以參考《演算法》第四版的 5.1 字串排序章節。

優化**(點選展開)

//參考**

////

#include #include #include #include #include #define maxn 1000010

#define maxm 127

using namespace std;

char str[maxn]; //字串陣列

int c[maxn]; //計數排序的桶

int ra[maxn],tempra[maxn];

int sa[maxn],tempsa[maxn];

void count_sort(int k,int n,int m)

for(int i=1; i#include #include #include #include #define maxn 1000010

#define maxm 127

using namespace std;

char str[maxn];

int c[maxn];

int ra[maxn],tempra[maxn];

int sa[maxn],tempsa[maxn];

void count_sort(int k,int n,int m)

return -1;

}

(ps:等我補完多校再說)

挑戰程式設計競賽(第2版)《演算法》第四版《演算法導論》

以下兩篇個人強烈推薦。

字尾陣列入門,字尾陣列模板整理

我自己懶得寫,就是想寫個部落格儲存下大佬的部落格位址 點這模板題 大佬的模板 include include include include include include include include include include include define inf 0x3f3f3f3f d...

2019 8 28字尾陣列入門

8月23的ccpc網賽出了神奇的字尾陣列。嚇死本寶寶了。啃了五天板子,還是沒太看懂。那麼先用起來,再慢慢體會吧。給你兩個字串,要求輸出最長公共子串長度。參見大佬的部落格 字串的任何乙個子串都是這個字串的某個字尾的字首。求a和b的最長公共子串等價於求a的字尾和b的字尾的最長公共字首的最大值。將ab串拼...

字尾陣列入門 SPOJ694

求單個子串的不重複字串的個數 t 20,len 1000 這是一道經典的字尾陣列入門題。由於剛開始學,對字尾陣列的理解還很抽象,於是拿這道題先找找感覺。首先,每個子串都可以理解成是某個字尾的字首,這是聯想到字尾陣列演算法的重要一步。接著,對於每乙個sa i 字尾陣列,含義為第i小的字尾的起始位置是s...