简易位图算法实现

基于字节数组实现位图算法增删改查:

package com.wmp.test;

import java.util.ArrayList;
import java.util.List;

public class BitList {

    private byte[] bits;
    private static final int MOVE_STEP = 0x3;
    private static final int TAIL_SURPLAS = 0x7;

    /**
     * 初始化容器大小
     * @param init
     * @throws Exception
     */
    public BitList(int init) throws Exception {

        if (init < 0) throw new Exception("Negative init number!");
        int index = getIndex(init);
        int length = index + 1;
        bits = new byte[length];
    }

    /**
     * 获取字节索引
     * @param num
     * @return
     * @throws Exception
     */
    private int getIndex(int num) throws Exception {
        return num >> MOVE_STEP;
    }

    /**
     * 获取位索引(从左到右,从0开始)
     * @param num
     * @return
     * @throws Exception
     */
    private int getOffset(int num) throws Exception {
        return num & TAIL_SURPLAS;
    }

    /**
     * 插入一个数
     * @param num
     * @throws Exception
     */
    public void add(int num) throws Exception {

        int capacity = getCapacity();
        if (num < 0 || num > capacity) {
            throw new OperatorNumOverLimit(num, capacity);
        }
        int index = getIndex(num);
        int offset = getOffset(num);
        addBit(index, offset);
    }

    /**
     * 删除一个数据
     * @param num
     * @throws Exception
     */
    public void remove(int num) throws Exception {

        int capacity = getCapacity();
        if (num < 0 || num > capacity) {
            throw new OperatorNumOverLimit(num, capacity);
        }
        int index = getIndex(num);
        int offset = getOffset(num);
        removeBit(index, offset);
    }

    /**
     * 是否存在
     * @param num
     * @return
     */
    public boolean exist(int num) throws Exception {
        int capacity = getCapacity();
        if (num < 0 || num > capacity) {
            throw new OperatorNumOverLimit(num, capacity);
        }
        int index = getIndex(num);
        int offset = getOffset(num);
        return existBit(index, offset);
    }

    /**
     * 数据提取
     * @return
     */
    public List<Integer> toList() {

        List<Integer> list = new ArrayList<>();
        byte target;
        boolean exist = false;
        int num;
        for (int i = 0; i < bits.length; i++) {
            target = bits[i];
            for (int j = 0; j < 8; j++) {
                exist = existBit(i, j);
                if (exist) {
                    num = i * 8 + j;
                    list.add(num);
                }
            }
        }
        return list;
    }

    /**
     * 按位查询
     * @param index
     * @param offset
     * @return
     */
    private boolean existBit(int index, int offset) {

        byte target = bits[index];
        int b = target & (0b1 << (TAIL_SURPLAS - offset));
        return b > 0;
    }

    /**
     * 按位置1
     * @param index
     * @param offset
     */
    private void addBit(int index, int offset) {
        bits[index] = (byte) (bits[index] | (0b1 << (TAIL_SURPLAS - offset)));
    }

    /**
     * 按位置0
     * @param index
     * @param offset
     */
    private void removeBit(int index, int offset) {
        bits[index] = (byte) (bits[index] & ( ~(0b1 << (TAIL_SURPLAS - offset))));
    }

    /**
     * 默认容量
     * @return
     */
    public int getCapacity() {
        return 8 * bits.length - 1;
    }

    /**
     * 操作数据越界异常
     */
    private static class OperatorNumOverLimit extends Exception {

        public OperatorNumOverLimit(int num, int capacity) {
            super("OperatorNum " + num + " over defined capacity range[0, " + capacity + "]");
        }
    }

}

 

代码测试:

    public static void main(String[] args) throws Exception {

        BitList list = new BitList(100);
        list.add(0);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(3);
        list.add(89);
        list.add(72);
        list.add(14);
        list.add(6);
        list.add(3);
        list.remove(0);
        list.remove(1);

        System.out.println(list.toList());
        System.out.println(list.exist(100));

    }

 

执行结果:

[2, 3, 6, 14, 72, 89]
false

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值