位图在索引, 数据压缩等方面有广泛应用
1. 文件包含1千万条电话号码记录(10**7次方),每条记录都是7位整数,没有重复的整数。要求对文件进行排序,注意大约只有1MB的内存空间可用,有充足的磁盘存储空间可用。请设计一个高效的算法。
2. 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中
遇到这种问题, 我们肯定不能再草草下笔. 选择一种好的数据结构往往能迅速解决问题.
#define INT_BITS (8*sizeof(int)) //每个int所能提供的位数
#define SHIFT 5 //我们假设int大小为32位,处理数据中的某个整数i就是位图中锁第 i<<5 个整数, 相当于 i / 32
#define MASK 0x1f //这是处理数据中的某整数i在位图中某个整数的第 i & MASK 位
//i & 31 就相当于 i % 32求模
#define MAX 1024 * 1024 //主要看实际需要用到的大小
int bitmap[1+MAX / INT_BITS]; //除法可能导致少一位整数, 于是加一
#define SET(i) do{
bitmap[i >> SHIFT] |= (1 << (i & MASK));
}while
#define CLEAR(i) do{
bitmap[i >> SHIFT] &= ~(1 << (i & MASK));
}while
#define TEST(i) (bitmap[ i>>SHIFT ] & (1 << (i & MASK)))
是的, 就这么点, 简单实用
现在拿上面的头文件去解决第一个问题:
#include <stdio.h>
#include "bitmap.h"
int main(void){
int i;
for(i=0;i<MAX;++i)
CLEAR(i);
while(scanf("%d",&i)!=EOF) //输入要排序的整数
SET(i);
for(i=0;i<MAX;++i)
if(TEST(i))
printf("%d/n",i);
return 0;
}
那么第二个问题也就能立刻解决了