字尾陣列 (suffix array)指某個字串的所有字尾按字典排序後得到的陣列。陣列中只儲存字尾開始的位置。簡稱sa。
字尾:從某個字串的某個開始位置到其末尾的字串子串,包括原串和空字串。例子:的字尾,,,{}
字典排序: 預設從小到大開始以長度為1的字尾字串為排序規則對其sa進行排序,並求出其排名rank(藍色區域)
以長度k的字尾字串的rank為排序規則對sa排序,求出長度為2k的字尾字串的排序結果.並求出長度為2k的rank.原因:長度為2k的字尾字串的rank總能由長度為k的字尾字串的rank求出(綠色區域->綠色區域)
重複步驟2 直到構造出完整的sa。
(圖:以之前的rank構造新的rank的過程)
下面給出用未優化後的**。
未優化**(點選展開)
(ps:等我補完多校再說)#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;
}
挑戰程式設計競賽(第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...