后缀数组(不完善)

前天在看后缀数组相关的内容时,看了罗穗骞的论文,看了2天才基本看懂了论文中的2倍增法。但是还是没有理解完全。现在先做一个笔记,以便以后参考。(说实话,我觉得trie, p - trie什么的都没这么伤脑筋),以下是我在网上down的一个示例程序。

#include<stdio.h> 
#include<string.h> 
#include<algorithm> 
using namespace std; 
int cmp(int *r,int a,int b,int l){ 
    return r[a]==r[b]&&r[a+l]==r[b+l]; 
} 
//为什么设置为100结果就不正确呢
#define M 200
int wa[M],wb[M],wv[M],ws[M]; 
int SA[M]; 
 
char s[M]="aabaaaab"; 
 
void print(char *label,int *arr,int n){ 
    puts(label); 
    for(int i=0;i<n;i++) 
        printf("%d ",arr[i]); 
    puts(""); 
} 
void da(char *r,int *sa,int n,int m){ 
     int i, j, p, *x = wa, *y = wb; 
     for (i = 0; i < m; i++) 
         ws[i] = 0; 
     for (i = 0; i < n; i++)
         ws[x[i] = r[i]]++; 
     for (i = 1; i < m; i++) 
         ws[i] += ws[i - 1]; 
     for (i = n - 1; i >= 0; i--) 
         sa[--ws[x[i]]] = i; 
     print("array sa:",sa,n); //**************print************** 
 
     for (j = 1, p = 1; p < n; j *= 2,m=p) 
     { 
         //对第二关键字进行排序:由上一次的结果 直接算出来 
         for (p = 0, i = n - j; i < n; i++) y[p++] = i; 
         for (i = 0; i < n; i++) 
             if (sa[i] >= j) y[p++] = sa[i] - j; 
         print("array y:",y,n); 
		print("array x:",x,n); 
         //对第一关键字进行排序 
         for (i = 0; i < n; i++) wv[i] = x[y[i]]; //根据第二关键字的顺序将后缀数组进行排序以便用于第一关键字的排序,注意论文中的图xy,
		 //先进行y排序,然后进行x排序。注意看论文中的图2,每次都是先根据上一次的结果算出第二个关键字的顺序放在y中,然后y的排序结果
		//对第一个关键字即图中的x进行排序。
         print("wv:",wv,n);//************************************** 
         for (i = 0; i < m; i++) ws[i] = 0; 
         for (i = 0; i < n; i++) ws[wv[i]]++; 
         for (i = 1; i < m; i++) ws[i] += ws[i - 1]; 
         for (i = n - 1; i >= 0; i--) sa[--ws[ wv[i]]] = y[i]; 
		 print("sa:",SA,n+1);//**************print************** 
         for ( p = 1, y[sa[0]] = 0, i = 1; i < n; i++) 
            y[sa[i]] = cmp(x, sa[i - 1], sa[i], j) ? p - 1 : p++; 
		 print("array y:",y,n);
	     print("array x:",x,n); 
         swap(x, y); 
		 printf("----------------------------------------\n");
     } 
} 
#define  maxn 100
int rank[maxn],height[maxn];
void calheight(char*r,int*sa,int n)
{
	int i,j,k=0;
	for(i=1;i<=n;i++)rank[sa[i]]=i;
	for(i=0;i<n;height[rank[i++]]=k)
	for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
		return;
}
int main(){ 
    int n=strlen(s);
	printf("n = %d\n",n);
    int m=128; 
    da(s,SA,n + 1,m); 
    print("sa:",SA,n + 1);//**************print************** 
	for (int i = 0; i <= n; ++i)
	{
		printf("%s\n",&s[SA[i]]);
	}
	calheight(s,SA,n + 1);
	print("height:",height,n + 1);
    return 0; 
} 
/* 
 * sa: 
   8 3 4 5 0 6 1 7 2 
 * */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值