2路bit-map的应用:test.txt中有42亿个无符号整数,从小到大打印其中只出现过一次的数 。限制: 可用内存为1.5GB.
2015-06-28 18:17
447 查看
先看这样一个问题:test.txt中有42亿个无符号整数,从小到大打印其中只出现过一次的数 。限制: 可用内存为1.5GB.
前面, 我们已经深入讨论了bit-map, 在本文中, 我们来看看2路bit-map, 其实, 它无非是对bit-map的扩展, 用了两个数组而已罢了。 既然已经熟悉了bit-map, 那我就不多啰嗦了, 直接给出代码:
OK, 2路bit-map的介绍到此为止, 多路bit-map与此同理, 简单。
前面, 我们已经深入讨论了bit-map, 在本文中, 我们来看看2路bit-map, 其实, 它无非是对bit-map的扩展, 用了两个数组而已罢了。 既然已经熟悉了bit-map, 那我就不多啰嗦了, 直接给出代码:
#include <iostream> #include <fstream> using namespace std; #define BIT_INT 32 // 1个unsigned int可以标志32个坑 #define SHIFT 5 #define MASK 0x1f #define N 4294967296 // 2的32次方 unsigned int *a = NULL; unsigned int *b = NULL; // 标志数组a还是b(其实,a、b本是指针) enum { arrA, arrB }; // 必须用堆 void createArr() { a = new unsigned int[1 + N / BIT_INT]; b = new unsigned int[1 + N / BIT_INT]; } void deleteArr() { delete []a; a = NULL; delete []b; b = NULL; } // 将所有位都初始化为0状态 void setAllZero() { memset(a, 0, (1 + N / BIT_INT) * sizeof(unsigned int)); memset(b, 0, (1 + N / BIT_INT) * sizeof(unsigned int)); } // 设置第i位为1 void setOne(unsigned int i, int flag) { if(arrA == flag) { a[i >> SHIFT] |= (1 << (i & MASK)); } else { b[i >> SHIFT] |= (1 << (i & MASK)); } } // 设置第i位为1 void setZero(unsigned int i, int flag) { if(arrA == flag) { a[i >> SHIFT] &= ~(1 << (i & MASK)); } else { b[i >> SHIFT] &= ~(1 << (i & MASK)); } } // 检查第i位的值 int getState(unsigned int i, int flag) { if(arrA == flag) { return (a[i >> SHIFT] & (1 << (i & MASK))) && 1; } return (b[i >> SHIFT] & (1 << (i & MASK))) && 1; } void setStateFromFile() { ifstream cin("test.txt"); // 我测试的时候, 文件中的数据为:7 7 9 2 5 2 0 0 1 4 3 2 8 unsigned int n; while(cin >> n) { // 采用2路bitmap, 其中a数组表示高位, b数组表示低位 // ab组合, 00表示出现0次, 01表示出现1次, 10表示出现2次, 11表示出现次数大于2次 int aState = getState(n, arrA); int bState = getState(n, arrB); if(0 == aState && 0 == bState) // 当前记录为0次 { setOne(n, arrB); } else if(0 == aState && 1 == bState) // 当前记录为1次 { setOne(n, arrA); setZero(n, arrB); } else if(1 == aState && 0 == bState) // 当前记录为2次 { setOne(n, arrB); } else // 当前记录大于2次,不做处理 { NULL; } } } void printSingleNum() { unsigned int i = 0; unsigned int bits = (1 + N / BIT_INT) * sizeof(unsigned int); for(i = 0; i < bits; i++) { if(0 == getState(i, arrA) && 1 == getState(i, arrB)) { cout << i << " "; // 结果:1, 3, 4, 5, 8, 9 } } cout << endl; } int main() { createArr(); setAllZero(); setStateFromFile(); printSingleNum(); deleteArr(); return 0; }运行一下, 结果与预期相符。 我运行的时候, 电脑卡的厉害啊。大家在玩的时候, 可以把N的值尽量调小一点, 比如N为429.
OK, 2路bit-map的介绍到此为止, 多路bit-map与此同理, 简单。
相关文章推荐
- asp.net web API 的调用返回Json值 POST方式请求
- Google地图接口API之地图类型(六)
- java学习总结
- 【Android开发经验】Android举UI设计经验
- 完美破解理发师悖论
- 用rsync在copy时实现过滤
- 设计原则学习小结
- poj2662解题报告(Dijkstra算法)
- Cordys 设置 默认登入显页 和 Palettes fillter
- Ubuntu无法进入桌面系统怎么办
- Search in Rotated Sorted Array 二分查找循环移位的有序数组
- 关于inline与static的总结
- 查比某个列大所有记录里最小的
- 为Cmake工程设置默认的启动工程
- 华为机试—身份证号码验证
- 文章标题
- Bitlocker驱动器加密使用
- 理解SVG的viewport,viewBox,preserveAspectRatio
- iOS开发--漫谈内存管理(一)
- 隐藏安卓应用图标