用倍增法求后缀数组名次数组-JavaScript

Posted 巅峰蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用倍增法求后缀数组名次数组-JavaScript相关的知识,希望对你有一定的参考价值。

用倍增法求后缀数组、名次数组

sa为后缀数组、rank为名次数组

//二分查找法,返回最接近的位置和实际位置
function binary_find(id,hasSortArr){
    let l=0,r=hasSortArr.length;
    let index=-1;
    while(r-l>0){
        const m=(l+r)>>1;
        const mid=hasSortArr[m]
        //比较下坐标大小
        const order=id>mid?1:(id<mid?-1:0)

        if(order===1){
            l=Math.max(l+1,m)
        }else if(order===-1){
            r=Math.min(r-1,m)
        }else{
            l=r=m;
            index=m;
        }
    }
    return [(l+r)>>1,index]
}
//二分法去重排序
function binary_sort(str) {
    const sa=[]
    for(let i=0;i<str.length;i++){
        const [n,index]=binary_find(str[i],sa);
        if(index===-1){
            sa.splice(n,0,str[i])
        }
    }
    return sa;
}

//后缀数组之获取名次数组
function getRank(str) {
    let arr=str.split(‘‘);
    const sLen=arr.length;//总共排名长度
    let uarr=binary_sort(arr);//获取排序去重后的
    const rank=[];
    let run=true;
    let len=1;//最长相似字符
    while (run){
        const map={}
        uarr.forEach(function (k,v) {
            map[k]=v;
        })
        for(let i=0;i<sLen;i++){
            rank[i]=map[arr[i]];
        }
        if(uarr.length<sLen){
            for(let i=0;i<sLen;i++){
                const fz=i+len<sLen?rank[i+len]:0;
                arr[i]=rank[i]*uarr.length+fz;
            }
            len=len*2;
            uarr=binary_sort(arr)
        }else{
            run=false;
        }
    }
    //sa为后缀数组、rank为名次数组
    // const sa=[]
    // rank.forEach(function (v,k) {
    //     sa[v]=k;
    // })
    return rank
}
const str=‘* 处理请求到的 OCR 信息safsdfafd12你3123123‘;
console.log(getRank(str))
/*
[
   3,  2, 28, 31, 33, 30, 27, 32,  0,
  14, 13, 15,  1, 26, 29, 23, 17, 22,
  24, 19, 20, 16, 21, 18,  6,  9, 25,
  12,  5,  8, 11,  4,  7, 10
]
*/

 

 

以上是关于用倍增法求后缀数组名次数组-JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

算法倍增算法 - 后缀数组

POJ.2774.Long Long Message(后缀数组 倍增)

后缀数组之倍增算法

后缀数组(理解)

后缀数组-倍增法

后缀数组详解+模板