您的位置:首页 > 大数据

大数据-25亿个数找出不重复的整数-双层桶-代码

2014-11-09 11:07 211 查看
原理见:/article/8231063.html

// 25亿个整数中找出不重复的整数的个数,内存空间不足以容纳这25亿个整数
// 先将25亿个数划分为多个桶,后用bitmap进行判断 00 表示未出现, 01表示出现一次,11表示出现多次。
// 假设输入数据在d:/test/in.dat
// 本程序分成2^8个桶,分别是0~2^23-1,2^23~2^24-1,……
// 对于每个桶约等于10^7个整数,对应内存大小为约40MB,如果将其用bitmap存储内存可继续降低近到10MB

#include <iostream>
#include <fstream>
#include <conio.h>
#include <time.h>
using namespace std;

char *mypath = "d:/test/in.dat";
char *respath = "d:/test/res.dat";

char mark[3000001];// 近10M数据存储
void generatedata()
{
fstream oo(mypath,ios::in|ios::binary|ios::app);
srand(unsigned(time(NULL)));
for(int i=0;i<1000000;++i)
{
double dat = (double)rand()/RAND_MAX;
int x = (int)(dat*100000000);
oo.write((char*)&x,sizeof(int));
}
oo.close();
}
int myhash(int m)
{
return m/(1<<23);
}
//// 取mark[i]的第j段
int identify(int i,int j)
{
return (mark[i]>>(j*2))&3;
}
void setmark(int m)
{
int j = m%(1<<23);
int i = j/4;
int k = j%4;
if(identify(i,k) == 0)
mark[i] = mark[i]|(1<<k*2);
else if(identify(i,k)==1)
mark[i] = mark[i]|(3<<k*2);
}
//// 将数据桶装到不同的不同的桶中假设分配2^8个桶d:/test/zerox.dat
void bucketprocess()
{
int temp;
char temppath[100];
fstream ino(mypath,ios::in|ios::binary);
while(ino.read((char*)&temp,sizeof(int)))
{
sprintf_s(temppath,99,"d:/test/zero%d.dat",myhash(temp));
fstream outo(temppath,ios::out|ios::binary|ios::app);
outo.write((char*)&temp,sizeof(int));
outo.close();
}
ino.close();
}
// 对第x个桶的数据进行处理,并把未重复的输出到目标文件中
void readeachfile(int x)
{
char temppath[100];
int temp;
sprintf_s(temppath,99,"d:/test/zero%d.dat",x);
fstream in(temppath,ios::out|ios::in|ios::binary|ios::app);
memset(mark,0,sizeof(mark));
while(in.read((char*)&temp,sizeof(int))){
setmark(temp);
//cout<<temp<<endl;
}
temp = x*(1<<23);

fstream myout(respath,ios::in|ios::out|ios::app|ios::binary);
for(int i=0;i<sizeof(mark)/sizeof(char);++i)
{
for(int j=0;j<4;++j){
if(identify(i,j) == 1){
x = i*4+j+temp;
myout.write((char*)&x,sizeof(int));
}
}
}
in.close();
//myout.close();

}
int main()
{
// generatedata(); // 生成数据需取消注释
// bucketprocess(); // 用输出流数组,速度会快很多,这里未采用是为了节省空间

int num = 1<<8;
for(int i=0;i<num;++i)
readeachfile(i);

getch();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐