之前聊过很多与bitmap有关的东东, 今天我们来看这样一个问题:a.txt中有40亿个无符号整数, b.txt中有10000个无符号整数, 求交集。 可用内存:1G.
很简单, 还是用bitmap, 思路我就不说了, 因为思路完全在下面的代码中:
#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位为0
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;
}
// 用bitmap记录是否存在
void setStateFromFile()
{
ifstream cin("a.txt");
unsigned int n;
while(cin >> n)
{
setOne(n);
}
}
// 哈哈
void printCommonNumber()
{
ifstream cin("b.txt");
unsigned int n;
while(cin >> n)
{
if(1 == getState(n))
{
cout << n << " ";
}
}
cout << endl;
}
int main()
{
createArr();
setAllZero();
// a.txt: 4 5 7 2 9 2 4 8 0 11 (其实a.txt中可以有40亿个无符号整数)
// b.txt: 6 11 0 2 3 (其实b.txt中可以有10000个无符号整数)
setStateFromFile();
printCommonNumber(); // 11 0 2
deleteArr();
return 0;
}
OK, 不多说, 一切思路尽在代码之中。