• bitMap算法将字符串映射成数字,同时可以将数字映射成字符串-javascript


    ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串

    说明

    1、所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来存储数据,因此可以大大节省存储空间。

    2、ckHash函数类适用于做key-value的字符映射关系,利用字符串正则密钥给定一个值范围,以及bit长度len,将字符串映射成0-len之间的数字,同时将0-len之间的数字还原成字符串,这样能使空间的利用率很高,准确度100%(数字和字符一一对应的关系)。

    3、最下面包含BitMap算法的实现,字符查询以及去重

    用途:

    bitMap算法之ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串,

    用于数据压缩,加密解密,以及bitMap大数据查询,去重

    作者:caoke

    demo测试100%通过

    //demo
    var d=new ckHash("http://www.baidu.com/[1~8dc-].[1~8dcv][1~8dcv]ml")
    // console.log(d.toString(11))
    // console.log(d.toNumber(d.toString(11)))
    
    for(var i=0;i< d.length;i++){
        const str=d.toString(i);
        const num=d.toNumber(str)
        console.log(str)
        console.log(i,num)
    }
    

      

    测试输出

    http://www.baidu.com/1.11ml
    0 0
    http://www.baidu.com/1.12ml
    1 1
    http://www.baidu.com/1.13ml
    2 2
    http://www.baidu.com/1.14ml
    3 3
    http://www.baidu.com/1.15ml
    4 4
    http://www.baidu.com/1.16ml
    5 5
    http://www.baidu.com/1.17ml
    6 6
    http://www.baidu.com/1.18ml
    7 7
    http://www.baidu.com/1.1dml
    8 8
    http://www.baidu.com/1.1cml
    9 9
    http://www.baidu.com/1.1vml
    10 10
    http://www.baidu.com/1.21ml
    11 11
    http://www.baidu.com/1.22ml
    12 12
    http://www.baidu.com/1.23ml
    13 13
    http://www.baidu.com/1.24ml
    14 14
    http://www.baidu.com/1.25ml
    15 15
    http://www.baidu.com/1.26ml
    16 16
    http://www.baidu.com/1.27ml
    17 17
    http://www.baidu.com/1.28ml
    18 18
    http://www.baidu.com/1.2dml
    19 19
    http://www.baidu.com/1.2cml
    20 20
    http://www.baidu.com/1.2vml
    此处省略1000行

    源码

    /*
    *  ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串,
    *  用于数据压缩,加密解密,以及bitMap大数据查询,去重
    *  作者:caoke
    * */
    
    class ckHash{
        //输入密钥
        constructor(secretKey){
            this.secretKey=secretKey;
    
            this.regexp=new RegExp(secretKey.replace(/[([^[]+?)]/g,function (m) {
                return '('+m.replace(/-/g,'\-').replace(/~/g,'-')+')'
            }).replace(/[\^:.?+]/g,'\$&'));
    
            this.lenArr=[];
            this.dataArr=[];
            secretKey.replace(/[([^[]+?)]/g,(m,p1)=>{
                const arr=[];
                for(let i=0;i<p1.length;i++){
                    if(p1[i]==='~'){
                        arr.push('~')
                    }else{
                        arr.push(p1[i].charCodeAt(0));
                    }
                }
                let length=0;
                for(let i=0;i<arr.length;i++){
                    if(arr[i]==='~'){
                        length=length+arr[i+1]-arr[i-1];
                        i++;
                    }else{
                        length=length+1;
                    }
                }
                this.lenArr.push(length)
                this.dataArr.push(arr)
            })
            this.length=this.lenArr.reduce((x,y)=>x*y)
        }
        //将数字映射成字符串
        toString(number){
            const arr=[];
            for(let i=this.lenArr.length-1;i>0;i--){
                const n1=number%this.lenArr[i];
                arr.unshift(n1)
                number=Math.floor(number/this.lenArr[i]);
            }
            arr.unshift(number)
    
    
            const codeArr=[]
            for(let i=0;i<arr.length;i++){
                const dataArr=this.dataArr[i];
                let len= arr[i];
    
                let code;
                for(let j=0;j<dataArr.length;j++){
                    if(dataArr[j]==='~'){
                        if(len<dataArr[j+1]-dataArr[j-1]){
                            code=dataArr[j-1]+len+1;
                            break;
                        }else{
                            len=len-(dataArr[j+1]-dataArr[j-1]);
                            j++;
                        }
                    }else if(len===0){
                        code=dataArr[j]
                        break;
                    }else{
                        len--;
                    }
                }
                codeArr.push(String.fromCharCode(code))
            }
            let index=0;
            return this.secretKey.replace(/[([^[]+?)]/g,(m,p1)=>{
                return codeArr[index++];
            })
        }
        //将字符串映射成数字
        toNumber(string){
            if(this.regexp.test(string)){
                const arr=[]
                string.replace(this.regexp,function (m,p1) {
                    for(let i=1;i<arguments.length-2;i++){
                        arr.push(arguments[i].charCodeAt(0))
                    }
                });
    
                const lenArr=[]
                for(let i=0;i<arr.length;i++){
                    const dataArr=this.dataArr[i];
                    let len= 0;
                    for(let j=0;j<dataArr.length;j++){
                        if(dataArr[j]===arr[i]){
                            break;
                        }else if(dataArr[j]==='~'){
                            if(arr[i]<=dataArr[j+1]&&arr[i]>dataArr[j-1]){
                                len=len+arr[i]-dataArr[j-1]-1;
                                break;
                            }else{
                                len=len+dataArr[j+1]-dataArr[j-1];
                                j++;
                            }
                        }else{
                            len++;
                        }
                    }
                    lenArr.push(len)
                }
                let number=0;
                let jz=1;
                for(let i=lenArr.length-1;i>=0;i--){
                    number=number+jz*lenArr[i];
                    jz=jz*this.lenArr[i]
                }
    
                return number;
    
            }else{
                throw string +' 不在匹配范围内';
            }
        }
    }
    
    //demo
    var d=new ckHash("http://www.baidu.com/[1~8dc-].[1~8dcv][1~8dcv]ml")
    // console.log(d.toString(11))
    // console.log(d.toNumber(d.toString(11)))
    
    for(var i=0;i< d.length;i++){
        const str=d.toString(i);
        const num=d.toNumber(str)
        console.log(str)
        console.log(i,num)
    }
    

        

    BItMap算法的实现

    //BitMap算法,大数据查询,算法复杂度O(1)
    class BitMap {
        constructor(secretKey){
            this.hashFunc=new ckHash(secretKey);
            this.length=this.hashFunc.length
            this.buffer=Buffer.alloc(this.length);
        }
        has(num){
            if(typeof num ==='string'){
                num=this.toNumber(num);
            }
            const n=num>>3;
            const k=num%8;
            return (this.buffer[n]&1<<k)!==0
        }
        toString(num){
            return this.hashFunc.toString(num);
        }
        toNumber(str){
            return this.hashFunc.toNumber(str);
        }
        set(num){
            if(typeof num ==='string'){
                num=this.toNumber(num);
            }
            const n=num>>3;
            const k=num%8;
            this.buffer[n]=this.buffer[n]|(1<<k);
        }
        del(num){
            if(typeof num ==='string'){
                num=this.toNumber(num);
            }
            const n=num>>3;
            const k=num%8;
            this.buffer[n]=this.buffer[n]&~(1<<k);
        }
    }
    
    //demo
    const b=new BitMap('http://www.baidu.com/[1~8dc-].[1~8dcv][1~8dcv]ml')
    
    for(var i=0;i< b.length;i++){
        const str=b.toString(i);
        const num=b.toNumber(str);
        console.log(i,num,str)
        //设置
        b.set(str)
    }
    
    for(var i=0;i< b.length;i++){
        const str=b.toString(i);
        //查询
        console.log(b.has(str),b.has(i))
    }
    console.log(b.buffer)
    

      

      

  • 相关阅读:
    软件需求分析阅读笔记2
    Ubuntu上的Hbase集群搭建
    Form的Load事件的添加
    软件需求与分析大作业进度(二)
    软件需求与分析大作业进度(一)
    第四周学习进度总结
    使用vmware+Ubuntu搭建hadoop集群
    团队十日冲刺10
    用户模板和用户场景
    团队十日冲刺9
  • 原文地址:https://www.cnblogs.com/caoke/p/10793885.html
Copyright © 2020-2023  润新知