字符串匹配之后缀数组
概念:后缀数组:是所有后缀按字典排序后,数组中记录的起始下标。sa[0]=5,起始下标为5的后缀
在所有后缀中字典最小。
rank数组:是给定后缀下标,返回字典顺序。rank[5]=0 rank[sa[i]]=i
后缀数组主要是为了匹配。子串:一定是某个后缀的前缀串
求height数组,height数组就是两个后缀的公共前缀的长度
可以用暴利求解法,但是复杂度高,可以用其它方法
根据rank排名和hg[rank[i]]>hg[rank[i-1]]+1,数学公式推理。
在一直后面为K的基础上可以知道,下次比较直接跳过k个字符,比较
k+1个,如果不相同,直接返回k,如果相同则k++
1,先求出原始的rank数组
2,根据i串排名获取rk值,rk-1获取前一个排名值。根据sa数组和rk的关系,求出
原始的串的位置j.然后比较i+k,j+k的字符是否相同。。
代码如下
public int[] getHeight(String src, Suff[] sa)
{
int src_length = src.length();
int [] rk = new int[src_length];
//rank表示为不重复排名0-n-1
for(int i=0;i<src_length;i++)
rk[sa[i].index] =i;
int [] hg = new int [src_length];
int k=0;
for(int i=0;i<src_length;i++)
int rk_i = rk[i];
if(rk_i==0){
hg[0]=0;
contine
}
int rk_i-1 = rk_i -1;
int j = sa[rankpre].index;
if(k>0)
k--;
for(;j+k<length&&i+k<length;k++)
{
if(src.charAt(j+k)!=src.charAt(i+k))
break;
}
hg[rk_i] = k;
}
return hg;