用倍增法求后缀数组、名次数组-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 ] */
标签:const,后缀,JavaScript,hasSortArr,let,数组,id,法求 来源: https://www.cnblogs.com/caoke/p/13195253.html