来看看这样一个问题:test.txt中有42亿个无符号整数, 求文件中有多少不重复的数(重复的数算一个)。限制: 可用内存为600MB.
思路很简单, 还是用bitmap, 无需多啰嗦, 大家可以直接参考我之前的与bit-map有关的博文:
http://blog.youkuaiyun.com/stpeace/article/details/46477239
http://blog.youkuaiyun.com/stpeace/article/details/46594797
http://blog.youkuaiyun.com/stpeace/article/details/46595517
下面, 我给出程序, 经验证, 结果ok, 程序如下:
#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;
// 必须用堆
void createArr()
{
a = new unsigned int[1 + N / BIT_INT];
}
void deleteArr()
{
delete []a;
a = NULL;
}
// 将所有位都初始化为0状态
void setAllZero()
{
memset(a, 0, (1 + N / BIT_INT) * sizeof(unsigned int));
}
// 设置第i位为1
void setOne(unsigned int i)
{
a[i >> SHIFT] |= (1 << (i & MASK));
}
// 设置第i位为1
void setZero(unsigned int i)
{
a[i >> SHIFT] &= ~(1 << (i & MASK));
}
// 检查第i位的值
int getState(unsigned int i)
{
return (a[i >> SHIFT] & (1 << (i & MASK))) && 1;
}
void setStateFromFile()
{
ifstream cin("test.txt"); // 我测试的时候, 文件中的数据为:7 8 9 2 5 2 6 0 1 4
unsigned int n;
while(cin >> n)
{
setOne(n);
}
}
int getNonDupNum()
{
unsigned int count = 0;
unsigned int i = 0;
unsigned int bits = (1 + N / BIT_INT) * sizeof(unsigned int);
for(i = 0; i < bits; i++)
{
if(1 == getState(i))
{
count++;
}
}
return count;
}
int main()
{
createArr();
setAllZero();
setStateFromFile();
cout << getNonDupNum() << endl; // 9, 也就是说, 文件中有9个不重复的数
deleteArr();
return 0;
}
OK, 不多说。