bit-map简介及其C/C++代码实现

来源:互联网 发布:免费画漫画软件 编辑:程序博客网 时间:2024/05/19 17:59

        在本文中, 我们来介绍一下bit-map,你可别以为这是什么bitmap图像, 那本文要介绍的bit-map是什么呢? 且听我慢慢道来。


        坐过火车没? 当你在火车上, 想拉屎的时候, 你得去上厕所啊。 屁颠屁颠爬到厕所处, 发现上面亮了一个灯, 表示里面有人, 你郁闷至极, 但无可奈何。 过了很久, 那个人出来了, 那个灯也就熄灭了, 你就可以上厕所了。

        这个灯, 就是计算机中的一个bit, 有两种状态 , 1表示有人在厕所中, 0表示没有人在厕所中。 所以, 从这个意义上说, 一个bit可以标志某事物的一个状态, 当这个bit与某事物状态建立映射后, 我说们, 形成了一个bit到事物状态的map.

         

        我们知道, 一个unsign char有8bit, 也就是说, 一个无符号字符可以标志某个厕所的8个坑位的状态, 下面我们看看程序:

#include <iostream>using namespace std;int main(void) {unsigned char c;// 8个坑位都没有人c = 0;// 8个坑位都有人c = 255;// 第1个(也可以认为是第0个)坑位有人c = 128;// 最后两个坑位有人c = 3;return 0;}
      看到没? 一个bit标志一个坑, 标志一个事物的状态, 那么一个unsigned char标志着8个事物的状态。 同理, 一个unsigned int标志着32个事物的状态, 其实一个int也可以标志着32个事物的状态。(当然, 这里所说的状态都是二值状态)


       现在, 假设有N个事物状态, 那至少需要多少个int来表示呢? 很显然是 N/32 + 1. 假设有100个事物(N=100), 那至少需要4个int (总共128位). 说的有点多了, 直接看程序吧:

#include <iostream>using namespace std;#define BIT_INT 32   // 1个int可以标志32个坑#define SHIFT 5#define MASK 0x1f#define N 100int a[1 + N / BIT_INT]; // 需要1 + N / BIT_INT 个整数来标志N个事物// 将所有位都初始化为0状态void setAllZero(){memset(a, 0, (1 + N / BIT_INT) * sizeof(int));}// 设置第i位为1, 表示有人在厕所里面void setOne(int i){a[i >> SHIFT] |= (1 << (i & MASK));}// 设置第i位为1, 表示没有人在厕所里面void setZero(int i){a[i >> SHIFT] &= ~(1 << (i & MASK));}// 检查第i位的值, 看看有没有人在厕所里面int getState(int i){return (a[i >> SHIFT] & (1 << (i & MASK))) && 1;}int main(void) {int bitNumber = (1 + N / BIT_INT) * BIT_INT;cout << bitNumber << endl;setAllZero();int i = 0;for(i = 0; i < bitNumber; i++){cout << getState(i);}cout << endl;setOne(0);setOne(1);setOne(2);setOne(3);setOne(4);for(i = 0; i < bitNumber; i++){cout << getState(i);}cout << endl;setZero(0);setZero(1);setZero(2);for(i = 0; i < bitNumber; i++){cout << getState(i);}cout << endl;return 0;}
      看看结果吧:

128
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
11111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
   

     果然, 结果与预期符合。


     我们再看程序:

#include <iostream>#include <set>using namespace std;#define BIT_INT 32   // 1个int可以标志32个坑#define SHIFT 5#define MASK 0x1f#define N 100int a[1 + N / BIT_INT]; // 需要1 + N / BIT_INT 个整数来标志N个事物// 产生伪随机数unsigned  int getRandom(){return rand();}// 将所有位都初始化为0状态void setAllZero(){memset(a, 0, (1 + N / BIT_INT) * sizeof(int));}// 设置第i位为1, 表示有人在厕所里面void setOne(int i){a[i >> SHIFT] |= (1 << (i & MASK));}// 设置第i位为1, 表示没有人在厕所里面void setZero(int i){a[i >> SHIFT] &= ~(1 << (i & MASK));}// 检查第i位的值, 看看有没有人在厕所里面int getState(int i){return (a[i >> SHIFT] & (1 << (i & MASK))) && 1;}int main(void) {int r = N;int size = 40; // 假设有40个事物(数字), 他们在[0, N-1]这个区间内// 构造40个互不相等的事物, 实际上, s中的元素是有序的, 但在该程序中, 我们不需要太关注这个set<int> s;while(size != s.size()){s.insert(getRandom() % r);}// 将所有坑位的人赶出来, 初始化setAllZero();set<int>::iterator it;for(it = s.begin(); it != s.end(); it++){setOne(*it); // 将事物*it与其对应的坑位*it联系起来, 当*it这个事物存在时, 对应的坑位*it的状态为1cout << *it << " ";}cout << endl;int i = 0;int bitNumber = (1 + N / BIT_INT) * BIT_INT;for(i = 0; i < bitNumber; i++){cout << i << "对应的坑位状态为:--->" << getState(i) << endl; // 获取坑位状态}cout << endl;return 0;}

      结果为:

0 2 3 4 5 11 12 16 18 21 22 24 26 27 33 34 35 36 38 41 42 45 47 53 58 61 62 64 67 69 71 73 78 81 82 91 92 94 95 99
0对应的坑位状态为:--->1
1对应的坑位状态为:--->0
2对应的坑位状态为:--->1
3对应的坑位状态为:--->1
4对应的坑位状态为:--->1
5对应的坑位状态为:--->1
6对应的坑位状态为:--->0
7对应的坑位状态为:--->0
8对应的坑位状态为:--->0
9对应的坑位状态为:--->0
10对应的坑位状态为:--->0
11对应的坑位状态为:--->1
12对应的坑位状态为:--->1
13对应的坑位状态为:--->0
14对应的坑位状态为:--->0
15对应的坑位状态为:--->0
16对应的坑位状态为:--->1
17对应的坑位状态为:--->0
18对应的坑位状态为:--->1
19对应的坑位状态为:--->0
20对应的坑位状态为:--->0
21对应的坑位状态为:--->1
22对应的坑位状态为:--->1
23对应的坑位状态为:--->0
24对应的坑位状态为:--->1
25对应的坑位状态为:--->0
26对应的坑位状态为:--->1
27对应的坑位状态为:--->1
28对应的坑位状态为:--->0
29对应的坑位状态为:--->0
30对应的坑位状态为:--->0
31对应的坑位状态为:--->0
32对应的坑位状态为:--->0
33对应的坑位状态为:--->1
34对应的坑位状态为:--->1
35对应的坑位状态为:--->1
36对应的坑位状态为:--->1
37对应的坑位状态为:--->0
38对应的坑位状态为:--->1
39对应的坑位状态为:--->0
40对应的坑位状态为:--->0
41对应的坑位状态为:--->1
42对应的坑位状态为:--->1
43对应的坑位状态为:--->0
44对应的坑位状态为:--->0
45对应的坑位状态为:--->1
46对应的坑位状态为:--->0
47对应的坑位状态为:--->1
48对应的坑位状态为:--->0
49对应的坑位状态为:--->0
50对应的坑位状态为:--->0
51对应的坑位状态为:--->0
52对应的坑位状态为:--->0
53对应的坑位状态为:--->1
54对应的坑位状态为:--->0
55对应的坑位状态为:--->0
56对应的坑位状态为:--->0
57对应的坑位状态为:--->0
58对应的坑位状态为:--->1
59对应的坑位状态为:--->0
60对应的坑位状态为:--->0
61对应的坑位状态为:--->1
62对应的坑位状态为:--->1
63对应的坑位状态为:--->0
64对应的坑位状态为:--->1
65对应的坑位状态为:--->0
66对应的坑位状态为:--->0
67对应的坑位状态为:--->1
68对应的坑位状态为:--->0
69对应的坑位状态为:--->1
70对应的坑位状态为:--->0
71对应的坑位状态为:--->1
72对应的坑位状态为:--->0
73对应的坑位状态为:--->1
74对应的坑位状态为:--->0
75对应的坑位状态为:--->0
76对应的坑位状态为:--->0
77对应的坑位状态为:--->0
78对应的坑位状态为:--->1
79对应的坑位状态为:--->0
80对应的坑位状态为:--->0
81对应的坑位状态为:--->1
82对应的坑位状态为:--->1
83对应的坑位状态为:--->0
84对应的坑位状态为:--->0
85对应的坑位状态为:--->0
86对应的坑位状态为:--->0
87对应的坑位状态为:--->0
88对应的坑位状态为:--->0
89对应的坑位状态为:--->0
90对应的坑位状态为:--->0
91对应的坑位状态为:--->1
92对应的坑位状态为:--->1
93对应的坑位状态为:--->0
94对应的坑位状态为:--->1
95对应的坑位状态为:--->1
96对应的坑位状态为:--->0
97对应的坑位状态为:--->0
98对应的坑位状态为:--->0
99对应的坑位状态为:--->1
100对应的坑位状态为:--->0
101对应的坑位状态为:--->0
102对应的坑位状态为:--->0
103对应的坑位状态为:--->0
104对应的坑位状态为:--->0
105对应的坑位状态为:--->0
106对应的坑位状态为:--->0
107对应的坑位状态为:--->0
108对应的坑位状态为:--->0
109对应的坑位状态为:--->0
110对应的坑位状态为:--->0
111对应的坑位状态为:--->0
112对应的坑位状态为:--->0
113对应的坑位状态为:--->0
114对应的坑位状态为:--->0
115对应的坑位状态为:--->0
116对应的坑位状态为:--->0
117对应的坑位状态为:--->0
118对应的坑位状态为:--->0
119对应的坑位状态为:--->0
120对应的坑位状态为:--->0
121对应的坑位状态为:--->0
122对应的坑位状态为:--->0
123对应的坑位状态为:--->0
124对应的坑位状态为:--->0
125对应的坑位状态为:--->0
126对应的坑位状态为:--->0
127对应的坑位状态为:--->0

       现在应该完成清楚了bit-map吧, 所谓bit-map, 实际上就是用一个bit去map一个事物的状态(二值状态). bit-map的好处是: 节省空间


       实际上, bit-map在大数据处理中经常会用到, 一些笔试面试题经常考, 后续我们会陆续介绍到。







0 0
原创粉丝点击