后缀数组的学习(五):calHeight实现代码分析

     把前面的倍增算法的内容看懂大概后,由于时间问题,就直接跳到calHeight()方法的研究中去!

     在实际应用,仅有sa数组是不够的,为了快速求解,还需要一个height数组!height数组的定义很容易理解:height[i]=suffix(sa[i-1])与suffix(sa[i])的最长公共前缀,也就是排名相邻的两个后缀的最长公共前缀!

    但是height的求解代码写得很晦涩,我只能说作者的水平很高,尽量缩短代码,但是真的给理解带来了难度!

    原代码是这样的:

 
 
  1. void calHeight(char *r,int *sa,int n){ 

  2.         int i,j,k=0; 

  3.         for(i=1;i<=n;i++)rank[sa[i]]=i; 

  4.         for(i=0;i<n;height[rank[i++]]=k) 

  5.         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 

  6.          

  7.  } 

非常短小精悍!为了便于理解,我改成这样的:

 
 
  1. void calHeight(char *r,int *sa,int n){ 
  2.         int i,j,k=0; 
  3.         for(i=1;i<=n;i++)rank[sa[i]]=i; 
  4.         for(i=0;i<n;height[rank[i++]]=k){ 
  5.             if(k>0)k--; 
  6.             j=sa[rank[i]-1]; 
  7.             for(;r[i+k]==r[j+k];k++); 
  8.         } 
  9.  } 

这样的话至少不会被代码本身的理解难到了!其实这里我们容易理解错的也只有三目运算符而已!就是k?k--:0,是三目运算符的内容,而j=sa[rank[i]];与三目运算符无关!

    而height的计算,我们可以从最原始的方法开始:那就是用相邻的两个后缀从首字母开始比较,直到后缀的两个字符不相等,但这样做的话就没有用到后缀的信息!所以呢可以定义一个h[i]数组,h[i]=height[rank[i]],即suffix(i)和它前一名的最长公共前缀。h数组有如下性质:h[i]>=h[i-1]-1

    为什么会有这样的性质的呢?论文中已经详细证明了!就是说:按照h[i]的递增顺序来计算就可以降低时间的复杂度!!

 

 
 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值