位图法

定义

位图法即 bitmap,就是用一个 bit 位来标记某个元素对应的 Value,而 Key 即是该元素。由于采用了 Bit 为单位来存储数据,因此在内存占用方面,可以大大节省。适用于大规模数据,但数据状态不是很多的情况。通常是用来判断某个数据存不存在

实现

应用

求集合的所有子集

集合有 n 个元素,它的子集的个数就是对这 n 个元素做组合,一共有n个位置可以组合,每个位置上该元素可以出现也可以不出现,所以最后总的个数为2的n次方。

这种状态只有两个,一共有 n 个位置的情况,完全适合适用位图。

对照图

因此只需要从 0 遍历到 2^n,即可将所有的子集遍历出来。然后再针对每一个值,去出相应位上的 bit 值,0 不出现在子集中,1 出现在子集中。

100亿整型数据去重

整型数据为 32 位最多有 2^32 (42亿多),所以 100 亿整型数据一定有重复的,2^32 个整形用位表示,需要 (2^32)bit == 512MB,需要 512MB 内存表示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>

#define MAX (0xffffffff)

/* 根据num将对应的MAP的bit位置1 */
void setBuf(char *buf, unsigned int num)
{
*(buf+(num>>0x3)) |= (0x1<<(num&0x7));
return;
}

/* 获取num对应的MAP的bit位值 */
unsigned int getBuf(char *buf, int num)
{
unsigned int flag = 0;
flag = ((*(buf+(num>>0x3)) & (0x1<<(num&0x7))) != 0)? 1:0;
return flag;
}

int main(int argc,char **argv)
{
if(argc < 2)
{
printf("usage:./a {0-9}*\n");
return 0;
}
unsigned int index = 1;
unsigned int num;
unsigned int max = 0;
char* buf = (char*)calloc((MAX>>0x3)+1,sizeof(char));
while(index < argc)
{
num = atoi(argv[index]);
max = max>num? max:num;
setBuf(buf,num);
++index;
}
for(index = 0; index <= max; index++)
{
if(getBuf(buf,index) == 1)
{
printf("id:%-10u flag:0x%-16x value:%-10u state:%-2d\n",
index>>0x3,
(unsigned int)buf[index>>0x3],
index,
getBuf(buf,index));
}
printf("process[%u]:%.2f%%\r",index,(float)(index)/max*100);
}
printf("\n");
return 0;
}

参考

作者

遇寻

发布于

2021-05-17

更新于

2021-08-22

许可协议

评论