字尾陣列 用字尾處理字串

2021-08-18 22:52:27 字數 1187 閱讀 2107

字尾陣列處理的是文字串。我們將文字串的每一條字尾拿出來,按照字典序排序,然後就可以處理字尾陣列了。字尾陣列sa[i]表示的就是排名第i位的字尾的第乙個字元所在下標。這可能有點繞口,所以我們用樣例解釋一下,如對於文字串ababa,則字尾為ababa,baba,aba,ba,a,我們排序後就是:a,aba,ababa,ba,baba,所以sa[1]=4(下標從0開始),表示排名為1的字尾(a)的下標為4;同理sa[2]=2,sa[3]=0,sa[4]=3,sa[5]=1。

既然知道了字尾陣列是什麼,我們就要開始構建字尾陣列了,如果我們直接用sort來排序,時間複雜度會比較的高,所以我們考慮使用基數排序,但我們這裡的基數排序並不一位一位的排,而可以使用倍增的演算法。

比如對於文字串ababa,我們先按第一位進行排序,則我們排序出來的陣列是,然後我們將每乙個二元組進行排序,每個二元組就是由上兩個元素構成的,所以我們構成的二元組是(最後的1沒有數可以與它構成二元組,相當於它的第二位是空,ascii最小),繼續將二元組構建成陣列,則排序出的陣列是,然後我們要將4個一起匹配,將4個一起匹配時,我們就要取我們算出的排序陣列裡的x項和x+2項了。(想想為什麼,可以根據下圖理解),出來的二元組是(實際上使4個元素,但每乙個元素又代表著乙個二元組,所以組出來的是二元組),排序出的陣列就是,到這裡就可以將所有的順序排除來了,然後我們按下標放入字尾陣列裡,出來的陣列就是正如上文所說。

在**中我們可以使用滾動陣列進行優化,因為有用的只有上一層和這層。

求字尾陣列的**:洛谷模板題

#include

#define maxn 2000005

using

namespace

std;

int read()

string s;

int n,p[maxn],c[maxn],sa[maxn],t[maxn],t2[maxn];

void build(int m)

}int main()

build(62);

for(int i=0;iprintf("%d ",sa[i]+1);

return

0;}

我們可以很簡易的想到二分,因為我們字尾陣列已經按照字典序排序,所以我們只要二分字尾陣列,然後與分到的字尾的字首進行比較即可。

字串 字尾陣列

n 字串的長度。m 當前字尾 離散化後 的值域。對於char可以跳過離散化,初值取128即可,對於int要離散化,初值取n即可,初值要保證覆蓋整個值域。sa i 排名為 i 的字尾的起始位置。rk i 起始位置為 i 的字尾的排名。驗證 const int maxn 1000000 10 int n...

字尾陣列 處理字串的有力工具

字尾陣列 處理字串的有力工具 年 月 摘要 字尾陣列是處理字串的有力工具。字尾陣列是字尾樹的乙個非常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也並不遜色,而且它比字尾樹所占用的記憶體空間小很多。可以說,在資訊學競賽中字尾陣列比字尾樹要更為實用。本文分兩部分。第一部...

字尾陣列以及利用字尾陣列求取最長公共字串

字尾樹組是乙個字串的所有字尾的排序陣列。字尾是指從某個位置 i 開始到整個串末尾結束的乙個子串。字串 r 的從 第 i 個字元開始的字尾表示為 suffix i 也就是suffix i r i.len r 如下圖所示 對於字串banana,所有的字尾字串是banana,anana,nana,ana,...