BitMap算法

BitMap

定义

BitMap基本原理是用一个bit位来标记某个元素对应的Value,而Key即是该元素。
由于采用了bit为单位来存储数据,因此会节约大量空间,适用于大规模数据。

举例

设有一个[1,2,5,7,11]数组,使用BitMap进行存储,如下图所示

image.png
定位:
行:index(n) = n / 8 = n >> 3
列:position(n) = n % 8 = n & 7
公式:a % b = a & (b-1), b = 2^n

添加元素
image.png

public void Add(int num)
{
    //num / 8得到位于数组的第几个byte
    int arrayIndex = num >> 3;
    //num % 8得到位于单个byte中第几位
    int position = num & 0x07;
    //将1左移position后,那个位置就是1,然后和以前的数据做|,那个位置就替换成1了。
    byte arg = (byte) ~(1 << position);
    Bits[arrayIndex] |= arg;
}

查找元素
image.png

public bool Contains(int num)
{
    //num / 8得到位于数组的第几个byte
    int arrayIndex = num >> 3;
    //num % 8得到位于单个byte中第几位
    int position = num & 0x07;
    //将1左移并取反
    byte arg = (byte) (1 << position);

    return (Bits[arrayIndex] & arg) != 0;
}

移除元素
image.png

public void Clear(int num)
{
    //num / 8得到位于数组的第儿个byte
    int arrayIndex = num >> 3;
    //num % 8得到位于单个byte中第几位
    int position = num & 0x07;
    //将1左移并取反
    byte arg = (byte) ~(1 << position);
    //随后&上即清除
    Bits[arrayIndex] &= arg;
}

完整代码

public class CustomBitMap
{
    public byte[] Bits { get; private set; }

    ///<summary>
    ///数组中的第几个byte
    ///</summary>
    public byte Index { get; private set; }

    ///<summary>
    ///在单个byte中第几位
    ///</summary>
    public byte Position { get; private set; }

    public CustomBitMap(int length = 8)
    {
        Bits     = new byte[length];
        Index    = 0;
        Position = 0;
    }

    ///summary>
    ///byte[]中所在的num位置变为1其他位置不变
    ///</summary>
    ///<param name="num"></param>
    public void Add(int num)
    {
        //num / 8得到位于数组的第几个byte
        int arrayIndex = num >> 3;
        //num % 8得到位于单个byte中第几位
        int position = num & 0x07;
        //将1左移position后,那个位置就是1,然后和以前的数据做|,那个位置就替换成1了。
        byte arg = (byte) ~(1 << position);
        Bits[arrayIndex] |= arg;
    }

    public void Clear(int num)
    {
        //num / 8得到位于数组的第儿个byte
        int arrayIndex = num >> 3;
        //num % 8得到位于单个byte中第几位
        int position = num & 0x07;
        //将1左移并取反
        byte arg = (byte) ~(1 << position);
        //随后&上即清除
        Bits[arrayIndex] &= arg;
    }

    public bool Contains(int num)
    {
        //num / 8得到位于数组的第几个byte
        int arrayIndex = num >> 3;
        //num % 8得到位于单个byte中第几位
        int position = num & 0x07;
        //将1左移并取反
        byte arg = (byte) (1 << position);

        return (Bits[arrayIndex] & arg) != 0;
    }
}

总结

优点
使用bit存储,节省空间
使用位运算,速度快

缺点
数据碰撞
数据稀疏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值