海量数据处理之bitmap实现
2013-05-08 20:23
295 查看
bitMap位图经常用来处理海量数据的问题,如3亿微信号和7亿QQ查重问题,电话号码去重问题,都可以用位图法来处理。
位图法思想较简单,即申请一个由比特构成的table,可在相应的位置置0或1.从而快速达到快速查找,同时又不会特别浪费空间。网上关于位图法的详细解释比较多。本文主要给出一个位图法简单的实现。
需要注意的问题:
1.计算好需要位图的大小以及范围。上面2^32个比特,下标范围0-2^32-1。
2.决定基本的存储方式。上面采用占8个比特的char
3.别忘了释放空间
例子:给一个int整数序列(数亿级),求连续数字最多为多少。如:100, 4, 200, 1, 3, 2 那么连续的数字最长为4(1,2,3,4)。
注意:
1.负数的处理,整理右移。int范围:-2^31~2^31-1,对所有的数加2^31,则范围变成:0~2^32-1。即正好是unsigned int的范围。适合了数组下标来表示。
2.2^32-1可以用0xffffffff来表示。
3.由于unsigned int类型的i无法递增到2^32所以for循环条件是‘<’而不是'<=',那么需在循环结束后在执行一次。
位图法思想较简单,即申请一个由比特构成的table,可在相应的位置置0或1.从而快速达到快速查找,同时又不会特别浪费空间。网上关于位图法的详细解释比较多。本文主要给出一个位图法简单的实现。
typedef char byte8; typedef byte8 * bitMap; int initBitMap(byte8 * & bitMap) { bitMap = (byte8 *)malloc(1 << 29); //bitMap size: 2^29 * sizeof(byte8) = 2^32; memset(bitMap, 0, 1 << 29); return 0; } int setBitTrue(byte8 * bitMap, unsigned int loc) { unsigned int segLength = sizeof(byte8) * 8; bitMap[loc / segLength] |= (1 << (segLength - 1 - loc % segLength)); return 0; } int isTrue(byte8 * bitMap, unsigned int loc) { unsigned int segLength = sizeof(byte8) * 8; int ret = bitMap[loc / segLength] & (1 << (segLength - 1 - loc % segLength)); return ret > 0 ? 1 : 0; } int destroyBitMap(byte8 * bitMap) { if (bitMap != NULL) { free(bitMap); } bitMap == NULL; return 1; }
需要注意的问题:
1.计算好需要位图的大小以及范围。上面2^32个比特,下标范围0-2^32-1。
2.决定基本的存储方式。上面采用占8个比特的char
3.别忘了释放空间
例子:给一个int整数序列(数亿级),求连续数字最多为多少。如:100, 4, 200, 1, 3, 2 那么连续的数字最长为4(1,2,3,4)。
int longestConsecutive(vector<int> &num) { bitMap bm; initBitMap(bm); unsigned int i = 0; for (i = 0; i < num.size(); i++) { unsigned int loc = num[i] + ((unsigned int)1 << 31); setBitTrue(bm, loc); } unsigned int max = 0; unsigned int count = 0; for (i = 0; i < 0xffffffff; i++) { if (isTrue(bm, i)) { count++; max = count > max ? count : max; } else { count = 0; } } if (isTrue(bm, i)) { //最后的0xffffffff count++; max = count > max ? count : max; } destroyBitMap(bm); return max; } int main() { int arr[] = {100, 4, 200, 1, 3, 2}; vector<int> num; num.assign(arr, arr + sizeof(arr) / sizeof(int)); printf("%u\n", longestConsecutive(num)); return 0; }
注意:
1.负数的处理,整理右移。int范围:-2^31~2^31-1,对所有的数加2^31,则范围变成:0~2^32-1。即正好是unsigned int的范围。适合了数组下标来表示。
2.2^32-1可以用0xffffffff来表示。
3.由于unsigned int类型的i无法递增到2^32所以for循环条件是‘<’而不是'<=',那么需在循环结束后在执行一次。
相关文章推荐
- 海量数据处理系列----C++中Bitmap算法的实现
- 海量数据处理系列----C++中Bitmap算法的实现
- 海量数据处理系列——C语言下实现bitmap算法
- bitmap处理海量数据及其实现
- 解析bitmap处理海量数据及其实现方法分析
- 海量数据处理系列----C++中Bitmap算法的实现
- 【转】 海量数据处理系列----C++中Bitmap算法的实现
- 海量数据处理系列----C++中Bitmap算法的实现
- 使用BitmapData实现图像的高速处理
- 2-bitmap实现海量数据查找不重复数据
- 海量数据处理——位图法bitmap
- [算法系列之十八]海量数据处理之BitMap
- 海量数据处理的 Top K算法(问题) 小顶堆实现
- 运用bitmap解决一道海量数据处理面试题:在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。
- Bitmap 海量数据处理
- 海量数据处理 bitmap算法实现32位压缩排序(位图排序)
- bitmap处理海量数据
- 使用bitmap处理海量数据
- 海量数据处理——位图法bitmap
- 海量数据处理问题(Top k问题)的实现