【数据结构】位图

前端之家收集整理的这篇文章主要介绍了【数据结构】位图前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

位图(bitmap),就是用每一位存放某种状态,适用于数据较多,且状态不多的情况。在Linux系统中,用位图来表示是否接收到进程发送的信号,接收到信号则将相关的比特位置1。

给出40亿个不重复的无符号整数,没排过序;在给定一个无符号的整数,判断这个数是不是在这40亿个数中。
这道题的解决方法也用到了位图,一个无符号的整数能表示的最大的值是2^32=42亿多,每一个无符号的整数占用4个字节,那么40亿个数据如果全部放在内存中需要16G,这显然是一般计算机做不到的。可以想到,一个数据要么存在,要么不存在,只有两种状态,因此,我们不妨使用比特位来存储这些数,存在的置为1,不存在的置为0。一个int类型占32位,存储这些数据大概需要500M,这个数据一般的计算机是可以接受的。这样,就可以判断这个数是不是在这40亿个数据中。

位图的优点是可以存储较多的数据,很适合解决上述类型的题目;缺点是是可读性差。

位图的主要操作都有:

  1. 置1操作
  2. 恢复为0
  3. 检测一个数是0还是1
  4. 位图中1的个数
  5. 位图中的总位数

下面来看一下位图的具体实现:

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. class BitMap
  6. {
  7. public:
  8. BitMap(size_t bitSet = 10)
  9. : _bitCount(bitSet)
  10. {
  11. _bitSet.resize((bitSet >> 5) + 1);//右移5位,就是除以32,将bit的位数转成字节数
  12. }
  13. void Set(size_t whichBit) //置1
  14. {
  15. size_t index = whichBit >> 5;
  16. if (whichBit < _bitCount)
  17. _bitSet[index] |= 1 << (whichBit % 32);//A|0=A 0|1=1
  18. }
  19. void ReSet(size_t whichBit) //恢复0
  20. {
  21. size_t index = whichBit >> 5;
  22. if (whichBit < _bitCount)
  23. _bitSet[index] &= ~(1 << (whichBit % 32));//A&1=A 1&0=0
  24. //也可以用异或:相同为0,相异为1 A^0=A 1^1=0
  25. }
  26. bool Test(size_t whichBit)//0返回0,1返回非0
  27. {
  28. size_t index = whichBit >> 5;
  29. if (whichBit < _bitCount)
  30. return _bitSet[index] & (1 << (whichBit % 32));//0&1=0 1&1=1
  31. cout << "比特位不存在" << endl;
  32. return false;
  33. }
  34. size_t Count()const //1的个数
  35. {
  36. char* pBitCount = "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4";
  37. size_t count = 0;
  38. for (size_t i = 0; i < _bitSet.size(); i++)
  39. {
  40. int value = _bitSet[i];
  41. int j = 0;
  42. while (j < sizeof(int))//j<4 一次一个字节
  43. {
  44. count += pBitCount[value & 0x0F]; //取低四位 & 0000 1111
  45. value >>= 4;
  46. count += pBitCount[value & 0x0F]; //再取四位
  47. value >>= 4;
  48. j++;
  49. }
  50. }
  51. return count;
  52. }
  53. size_t Size()const
  54. {
  55. return _bitCount;
  56. }
  57. private:
  58. vector<int> _bitSet;
  59. size_t _bitCount;
  60. };
  61.  
  62. void test()
  63. {
  64. BitMap bmp(50);
  65. bmp.Set(20);
  66. bmp.Set(40);
  67. bmp.Set(40);
  68. bmp.Set(15);
  69. bmp.Set(60);
  70. if (bmp.Test(10))
  71. cout << "第10位是1" << endl;
  72. else
  73. cout << "第10位是0" << endl;
  74.  
  75. cout << "bit位数" << bmp.Size() << endl;
  76. cout << "bit位1的个数" << bmp.Count() << endl;
  77.  
  78. bmp.ReSet(40);
  79. cout << "bit位1的个数" << bmp.Count() << endl;
  80. }
  81. int main()
  82. {
  83. test();
  84. return 0;
  85. }

运行结果:

猜你在找的数据结构相关文章