关于一个BitMap的算法理解

发布时间 2023-09-19 10:21:42作者: 伟衙内

  最近在看算法,想学习一下算法这玩意,虽然工作中很少用到。在《小灰的算法之旅》这本书中,有一个关于BitMap的算法。

   早期接触过一点类似的,有人在数据库里面保存了一个字符串   000000000000000000,000000000001000001,这种,每一位代表一个含义,比如第一位为1表示这个用户是上海用户,第二位为1表示星级客户,第三位为1表示有借贷,第四位为1表示有信用卡,等等,每一位是一个标志信息。

  代码如下,注释已经很明显的标注了,当然也可以用128位的数组表示等都行,主要是标志位,同时表示标志位的含义。

class Solution {

    private long[] words;

    private int size;

    /**
     * 下面算法就是相当于声明128位都是00000000的二进制,
     * 如果某一位上有值则设值为1,
     * 就相当于linux中设置权限   7代表  rwx  111
     *                       6代表   rw_  110
     *                       5代表   r_x  101
     *                       4代表   r__  100
     *                       3代表   _wx  011
     *                       2代表   _w_  010
     *                       1代表   __x  001
     *                       0代表   ___  000
     *   每一位数字上0表示无权限,1表示有权限
     *
     *   下面算法是一样的,只不过是用128位来表示
     * @param size
     */
    public Solution(int size){
        this.size = size;
        this.words = new long[(getWordIndex(size-1)+1)]; //初始化后值都是0,相当于二进制为[0000,0000]
    }

    public boolean getBit(int bitIndex){
        int wordIndex = getWordIndex(bitIndex);
        return (words[wordIndex]&(1L<<bitIndex))!=0;//此处相当于判断某一位上是否是1,如果是说明设值了
    }

    public void setBit(int bitIndex){
        int wordIndex = getWordIndex(bitIndex);
        //把 1 左移 bitIndex 位   相当于  00001左移 bitIndex位,保证某位上是1
        words[wordIndex] |= (1L<<bitIndex);

        /**
         * bitIndex为0   word[0] = 1
         * bitIndex为1   word[0] = 10
         * bitIndex为2   word[0] = 100
         * bitIndex为3   word[0] = 1000
         *
         * bitIndex为64  word[1] = 1
         * bitIndex为65  word[1] = 10
         * bitIndex为66  word[1] = 100
         * bitIndex为67  word[1] = 1000
         *
         * 上述用的是  或 操作,
         * 所以如果我设值bitIndex=0,再bitIndex为1  那么  word[0] = 11
         * 如果我设值bitIndex=0,再bitIndex为3  那么  word[0] = 1001
         */
    }

    private int getWordIndex(int bitIndex){
        //把 bitIndex 右移 6位,相当于除以64
        return bitIndex>>6;
    }

    private void printWords(){
        for (long word : words) {
            System.out.println(Long.toBinaryString(word));
        }
    }

    public static void main(String[] args) {
        
            Solution s= new Solution(128); //下面数字设值不能超过128, 即范围为 [0,128)
            s.setBit(65);
//            s.setBit(75);
//            s.setBit(36);
//            s.setBit(41);

            s.printWords();

//        System.out.println(s.getBit(126));  // false
//        System.out.println(s.getBit(78)); //false
//        System.out.println(s.getBit(36)); //true

    }
}