BitMap
定义
BitMap基本原理是用一个bit位来标记某个元素对应的Value,而Key即是该元素。
由于采用了bit为单位来存储数据,因此会节约大量空间,适用于大规模数据。
举例
设有一个[1,2,5,7,11]数组,使用BitMap进行存储,如下图所示
定位:
行:index(n) = n / 8 = n >> 3
列:position(n) = n % 8 = n & 7
公式:a % b = a & (b-1), b = 2^n
添加元素
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 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;
}
移除元素
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存储,节省空间
使用位运算,速度快
缺点
数据碰撞
数据稀疏