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)

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM