"Suffix array" study notes

Suffix array construction

NOTE: string in Table 1 from the beginning.

$ Sa $ suffix array defined

$ Sa_i $ express lexicographical rank as the starting position $ i $ suffix.

thought

The number of comparisons using violence to quickly sort the $ n $ suffix sorting is $ n \ log n $, but a comparison of time complexity is $ O (n) $. Resulting in a total complexity is $ O (n ^ 2 \ log n) $.

$ Manber $ & $ Mayer $ multiplication method, based on the radix sorting is performed each time before the $ 2 ^ k $ suffix of each element, the complexity of $ O (n \ log n) $. The central idea is that because unlike the ordinary between suffix and suffix numbers, we want to sort the object itself is linked to the interior. After each suffix drained before $ 2 ^ k $ elements in order to discharge $ 2 ^ {k + 1} $ one, but two is a $ 2 ^ k $ is put together. And because all have been $ 2 ^ k $ sorted, we will know the $ 2 ^ k $ relative relationship, so it will be to sort the problem into tuple. This can be utilized radix sort $ O (n) $ completed.

Radix sort idea is to use the second key has been ordered, the first sort key. This ensures that for each of the first key, a second key is ordered. So the whole sorted.

/*DennyQi 2019*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1000010;
inline int read(){
    int x(0),w(1); char c = getchar();
    while(c^'-' && (c<'0' || c>'9')) c = getchar();
    if(c=='-') w = -1, c = getchar();
    while(c>='0' && c<='9') x = (x<<3)+(x<<1)+c-'0', c = getchar(); 
    return x*w;
}
char s[N];
int n,x[N],y[N],c[N],sa[N];
inline void BuildSA(int m){
    int p;
    for(int i = 1; i <= n; ++i) ++c[x[i] = s[i]];
    for(int i = 1; i <= m; ++i) c[i] += c[i-1];
    for(int i = n; i >= 1; --i) sa[c[x[i]]--] = i;
    for(int k = 1; k <= n; k += k){
        p = 0;
        for(int i = n-k+1; i <= n; ++i) y[++p] = i;
        for(int i = 1; i <= n; ++i) if(sa[i] > k) y[++p] = sa[i]-k;
        for(int i = 1; i <= m; ++i) c[i] = 0;
        for(int i = 1; i <= n; ++i) ++c[x[i]];
        for(int i = 1; i <= m; ++i) c[i] += c[i-1];
        for(int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i], y[i] = 0;
        swap(x,y);
        x[sa[1]] = 1, p = 1;
        for(int i = 2; i <= n; ++i) x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k]) ? p : ++p;
        if(p >= n) break;
        m = p;
    }
}
int main(){
    // freopen(".in","r",stdin);
    scanf("%s",s+1);
    n = strlen(s+1), 
    BuildSA('z'+1);
    for(int i = 1; i <= n; ++i) printf("%d ",sa[i]);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/qixingzhi/p/11015673.html