倍增算法实现后缀数组

reference:http://baike.baidu.com/view/1240197.htm

in:string out:suffix array 

#include<stdio.h>
#include<stdlib.h>
#define maxn 100
void changeabc(int* r, char* c)//将字符串转换为数字 
{
    int i = 0;
    for(;*c != '\0';c++, i++)
        if(*c <= 'Z' && *c >= 'A') r[i] = *c - 64;
        else if(*c <= 'z' && *c >= 'a') r[i] = *c - 70;
        else printf("error\n");
    r[i] = 0;            
}

bool cmp(int *r, int i, int j, int l)
{
    return r[i] == r[j] && r[i + l] == r[j + l];
}

void suffix_ar(int* r, int* sa, int n, int m)
{
    int  wa[maxn], i, secondkey[maxn], rank[maxn], j, *y = secondkey, *x = rank, *t, p;
    
    for(i = 0; i <= m; i++) wa[i] = 0;
    for(i = 0; i <= n - 1; i++) wa[x[i] = r[i]]++;
    for(i = 0; i <= m; i++) wa[i] += wa[i - 1];
    for(i = n - 1; i >=0; i--) sa[--wa[x[i]]] = i;
    
    for(p = 1, j = 1; p < n; j *= 2, m = p)
    {
        for(p = 0, i = n - 1; i >= n - j; i--, p++) y[p] = i;
        for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i] - j;//second key 
        
        for(i = 0; i <= m; i++) wa[i] = 0;
        for(i = 0; i <= n - 1; i++) wa[x[y[i]]]++;
        for(i = 0; i <= m; i++) wa[i] += wa[i - 1];
        for(i = n - 1; i >=0; i--) sa[--wa[x[y[i]]]] = y[i];
        
        for(x = t, x = y, y = t, x[sa[0]] = 0, i = 1, p = 1; i < n; i++)
            x[sa[i]] = cmp(y, sa[i], sa[i - 1], j)?p - 1:p++;
    }
    
} 
 
main()
{
    int r[maxn], sa[maxn], i, j;
    char c[100];
    printf("please enter the string:");
    scanf("%s", c);
    for(i = 0; c[i] != '\0'; i++);
    changeabc(r, c);

    suffix_ar(r, sa, i + 1, 52);
    printf("suffix array:");
    for(j = 1; j <= i; j++)
        printf("%d ", sa[j]);
    printf("\n");
    for(j = 1; j <= i; j++)
        printf("%s\n", c + sa[j]);
        
    system("pause");
    return 0;
}



猜你喜欢

转载自blog.csdn.net/cx351864995/article/details/7632184