由pos及lcp对在线字符串w在短文A中进行查找

利用二分法求Lw.

(1)直接利用已排列的pos数组进行求解.引入符号u^p表示字符串u的长度为p的前缀,u ≤P  v表示字符串u的长度为p的前缀小于v,引入字符串W=w0w1...wp-1(p<n),令

     Lw=min(k: W≤P Apos[k] or k=N)  and   Rw=max(k: Apos[k] ≤P W or k=-1) .

则W和A的某个字串匹配,当且仅当i=pos[k](k[Lw,Rw]).可以用二分法搜索进行计算Lw和Rw,时间复杂度为O(logn),又每次单独的字符比较需要O(P)的时间,所以总的时间复杂度为O(Plog(n)).

(2)为了降低时间复杂度,对(1)的方法进行改进,假定后缀数组的一组排列(L,...,R),M是其中心,则下次搜索将在(L,...,M)中进行,或在(M,...,R)中进行,又知 k=lcp(L,W)。

Case 1:k<lcp(L,M)

      说明M的第k+1个字符和L的第k+1个字符相等,因为W>M,所以下次查找在(M,R)中进行;

Case 2:k>lcp(L,M)

      说明W<M,所以下次查找在(L,M)中进行;

Case 3:k=lcp(L,M)

      说明L,M和W的前k个均相等,要判断下次循环在左半部分还是右半部分,需要比较M和W的第k+1个字符大小,若相等下次查找在(L,M)中进行,否则下次查找在(M,R)中进行。

继续循环直到k=p或L>=R。

由于W的所有字符均只查找了一次,所以总的时间复杂度为O(P+log(n) ).

利用Lcp进行全文二分法搜索

lcp(i,j)若为内部节点则为lcp[(i+j)/2],若为叶结点则为height[j].这里只能求得部分后缀的lcp.在字符串s中查找子字符w只需要O(log(n))时间。

/** 用O(1)的时间得到lcp(i,j) **/

int LCP(int i,int j){

    if(i==j-1)return height[j];

    return lcp[(i+j)/2];

}

/** 查找s中是否有子串w,若有返回w第一次出现的首字母索引,若无返回0 **/

int searching(char *w,int n,char *s,int l,int r,int k){

if(l>r-1)return -1;//说明S中不含w子串 

if(k==P)return Pos[l];//s中含有w子串 

int m=(l+r)/2;

while(s[Pos[l]+k]==w[k])//求lcp(l,w) 

k++;

if(k==P)return Pos[l];

if(l==r-1&&LCP(l,r)!=k){m=r;return -1;}//只要lcp(r-1,r)!=lcp(r-1,w)就不可能匹配 

/** 二分法搜索 **/

int L;

if(k<LCP(l,m))L=searching(w,n,s,m,r,k);//在m+1~r之间 

else if(k>LCP(l,m))L=searching(w,n,s,l,m,k);//在l+1~m-1之间 

else {

while(w[k]==s[Pos[m]+k]){

k++;

    if(k==P)return Pos[m];//与m匹配成功 

}

    if(l==r-1)return -1;//w和l及m/r都不可能匹配

    else if(Pos[m]+k==n||w[k]>s[Pos[m]])L=searching(w,n,s,m,r,k);//在 m+1~r之间 

else L=searching(w,n,s,l,m,k);//在l+1~m-1之间 

}

printf("L:%d Pos:%d\n",L,Pos[L]);

return L;

3.4结果分析

该字符串匹配问题也可用后缀树求解,通过自底向上遍历后缀树取代后缀数组的排序及lcp的计算,方法更为简洁,且在字母表内容很少而且确定时,后缀树的建立只需要O(n)时间,优于后缀数组O(log(n)),但后缀树所需要的空间是后缀数组的3~5倍,且后缀数组的搜索时间为O(P+log(n))与后缀树相近甚至在某些情况下优于后缀树。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值