• 后缀数组增量包算法


    //压缩增量包
    function MinChunk(chunkArr,s1) {
      var minChunk=[]
      for(let i=0;i<chunkArr.length;i++){
        let arr=chunkArr[i];
        if(arr[0]==='e'&&arr[2]<String(arr[1]).length+String(arr[2]).length){
          arr=['a',s1.substr(arr[1],arr[2])]
        }
        var lastArr=minChunk[minChunk.length-1];
        if(arr[0]==='a'&&lastArr&&lastArr[0]==='a'){
          lastArr[1]=lastArr[1]+arr[1];
        }else{
          minChunk.push(arr)
        }
      }
      const narr=[]
      for(let i=0;i<minChunk.length;i++){
        let arr=minChunk[i];
        if(arr[0]==='a'){
          narr.push(arr[1])
        }else if(arr[0]==='e'){
          narr.push([arr[1],arr[2]])
        }
      }
      return narr;
    }
    
    //比较两字符的相等长度和大小
    function compareLen(n1,n2,str1,str2) {
      //求出相等部分
      var len=0;
      while (n1+len<=str1.length&&n2+len<=str2.length&&str1.charCodeAt(n1+len)===str2.charCodeAt(n2+len)){
        len++;
      }
      //求出大小
      var dis=0;
      if(n1+len===str1.length){
        dis--
      }
      if(n2+len===str2.length){
        dis++
      }
      if(dis===0&&n1+len<str1.length&&n2+len<str2.length){
        if(str1.charCodeAt(n1+len)<str2.charCodeAt(n2+len)){
          dis--
        }else{
          dis++
        }
      }
      return [len,dis];
    }
    
    //查找字符在数组的最大相等长度和大小
    function findLen(str,hasSortArr,callback) {
      var l=0,r=hasSortArr.length;
      var lock=-1;
      var len1=0,len2=0;
      var len=0,dis=0;
    
      if(hasSortArr.length>0){
        [len1,dis]=callback(str,hasSortArr[0]);
        if(dis<1){
          return [0,len1,dis]
        }else{
          l=l+1;
        }
        [len2,dis]=callback(str,hasSortArr[r-1]);
        if(dis>-1){
          return [r-1,len2,dis]
        }else{
          r=r-1
        }
    
        if(l===r){
          if(len1>len2){
            return [r-1,len1,dis]
          }else{
            return [r,len2,dis]
          }
        }
        while(lock===-1){
          var m=(l+r)>>1;
          //比较下坐标大小
          [len,dis]=callback(str,hasSortArr[m])
          if(dis===1){
            if(l+1===r){
              if(len<len2){
                lock=r;
                len=len2;
                dis=-1
              }else{
                lock=m;
              }
            }else{
              len1=len;
              l=m
            }
          }else if(dis===-1){
            if(l+1===r){
              if(len<len1){
                lock=l;
                len=len1;
                dis=1
              }else{
                lock=m;
              }
            }else{
              len2=len;
              r=m
            }
          }else{
            lock=m;
          }
        }
        return [lock,len,dis]
      }
      return [0,0,1]
    }
    
    //SA[i]表示排名为i的后缀下标、rk[i]表示起始位置的下标为i的后缀的排名
    function getSa(str) {
      var sLen=str.length;//总共排名长度
      //后缀数组
      var sa=[];
      for(var i=0;i<sLen;i++){
        var [n,len,dis]=findLen(i,sa,function (n1,n2) {
          return compareLen(n1,n2,str,str)
        })
        if(dis===1){
          sa.splice(n+1,0,i)
        }else{
          sa.splice(n,0,i)
        }
    
      }
      return sa
    }
    //用后缀数组,求两个字符的公共子串,也就是两个文件的公共部分
    function makeChunk(s1,s2){
      var sa1=getSa(s1);//后缀数组,排序
      const chunkArr=[]
      let i=0;
      while (i<s2.length){
        var [n,len,dis]=findLen(i,sa1,function (n2,n1) {
          return compareLen(n2,n1,s2,s1)
        })
        if(len>0){
          chunkArr.push(['e',sa1[n],len])
          i=i+len;
        }else{
          chunkArr.push(['a',s2[i]])
          i++
        }
      }
      return chunkArr;
    }
    //执行增量包
    function execChunk(s1,chunk){
      var ns='';
      for(var i=0;i<chunk.length;i++){
        var arr=chunk[i];
        if(Object.prototype.toString.call(arr)==='[object Array]'){
          ns=ns+s1.substr(arr[0],arr[1])
        }else{
          ns=ns+arr
        }
      }
      return ns;
    }
    module.exports=function (s1,s2) {
      const chunk=makeChunk(s1,s2);
    
      const chunkArr=MinChunk(chunk,s1)
      if(execChunk(s1,chunkArr)!==s2){
        throw '增量包打包错误'
      }
      return chunkArr
    };
    

      

  • 相关阅读:
    TensorflowJS 教程
    理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)
    Wireshark 过滤 基本语法
    LSTM如何解决梯度消失或爆炸的?
    K-Means ++ 和 kmeans 区别
    LSTM UEBA异常检测——deeplog里其实提到了,就是多分类LSTM算法,结合LSTM预测误差来检测异常参数
    python 多进程练习 调用 os.system命令
    TLS 改变密码标准协议(Change Cipher Spec Protocol) 就是加密传输中每隔一段时间必须改变其加解密参数的协议
    ssl tls 证书链 根证书和叶证书查询
    TLS与SSL之间关系——SSL已经被IEFT组织废弃,你可以简单认为TLS是SSL的加强版
  • 原文地址:https://www.cnblogs.com/caoke/p/13691520.html
Copyright © 2020-2023  润新知