数组中查找匹配相同前缀的范围

//排名函数
const compareLen=function (str1,str2,start=0) {
  let dis=0;
  let len=0;
  while (dis===0&&start+len<str1.length&&len<str2.length){
    //超过字符,返回小于
    if(str1.charCodeAt(start+len)>str2.charCodeAt(len)){
      dis=1;
    }else if(str1.charCodeAt(start+len)<str2.charCodeAt(len)){
      dis=-1;
    }else{
      len++;
    }
  }
  if(start+len===str1.length&&len===str2.length){
    dis=0
  }else if(start+len===str1.length){
    dis=-1
  }else if(len===str2.length){
    dis=0
  }
  return dis;
};
function findLen(str,hasSortArr,callback,start) {
  let l=0,r=hasSortArr.length;
  let index=-1;
  if(hasSortArr.length>0){
    const ri=callback(str,hasSortArr[r-1],start);
    if(ri===1){
      return [r,r]
    }else if(ri===0){
      l=r-1;
      while (l>-1&&callback(str,hasSortArr[l-1],start)===0){
        l--;
      }
      return [l,r]
    }else{
      r=r-1;
    }
    const li=callback(str,hasSortArr[0],start);
    if(li===-1){
      return [0,0]
    }else if(li===0){
      r=l+1;
      while (r<hasSortArr.length&&callback(str,hasSortArr[r],start)===0){
        r++;
      }
      return [l,r]
    }else{
      l=l+1;
    }
    while(index===-1&&r-l>0){
      const m=(l+r)>>1;
      //比较下坐标大小
      const order=callback(str,hasSortArr[m],start)
      if(order===1){
        l=Math.max(l+1,m)
      }else if(order===-1){
        r=Math.min(r-1,m)
      }else{
        index=m;
      }
    }
    if(index===-1){
      return [l,r]
    }
    if(index-l>0){
      l=index;
      while(l>-1&&callback(str,hasSortArr[l-1],start)===0){
        l=l-1;
      }
    }
    if(r-index>1){
      r=index+1;
      while(r<hasSortArr.length&&callback(str,hasSortArr[r],start)===0){
        r=r+1;
      }
    }
  }
  return [l,r]
}
//相同的前缀开头
const arr=['a','b','b','c','d'];
const [start,end]=findLen('bc',arr,compareLen,0)
console.log([start,end])
原文地址:https://www.cnblogs.com/caoke/p/13293818.html