从2.5亿个数字里面找出不重复的数字的个数
2007-10-22 15:50
253 查看
整理自:http://topic.csdn.net/u/20070929/14/b183cd03-d780-4c59-a666-ab127f12f7b1.html
问题描述如下:
有2.5亿个整数(这2.5亿个整数存储在一个数组里面,至于数组是放在外存还是内存,没有进一步具体说明);
要求找出这2.5亿个数字里面,不重复的数字的个数(那些只出现一次的数字的数目);
另外,可用的内存限定为600M;
要求算法尽量高效,最优;
1. caoxic的算法
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
BYTE repmarks[2^25];//32M 32M*8>2.5亿 //标志2.5亿个数字数组里面的数字是否重复过
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//重复出现的数字的个数,例子:1 2 2 3 5 3 4 算2个
memset(marks,0,sizeof(marks));
memset(repmarks,0,sizeof(repmarks));
ASSERT(sizeof(repmarks)*8>=bufcount);//断言repmarks数组够用
for(dw=0;dw<bufcount;dw++)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
repmarks[dw>>3] |= bitmarks[dw&7];//标志pBuf[dw]这个数字出现重复
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(repmarks[dw>>3] & bitmarks[dw&7])//
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}
else
{
count2 ++; //重复的数字的数量
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];
}
}
}
return count-count2;
}
2. 改一下,应该也可以:
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
BYTE repmarks[2^25];//32M 32M*8>2.5亿 //标志2.5亿个数字数组里面的数字是否重复过
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//只出现一次数字的个数,例子:1 2 2 3 5 3 4 算3个
memset(marks,0,sizeof(marks));
memset(repmarks,0,sizeof(repmarks));
ASSERT(sizeof(repmarks)*8>=bufcount);//断言repmarks数组够用
for(dw=0;dw<bufcount;dw++)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
repmarks[dw>>3] |= bitmarks[dw&7];//标志pBuf[dw]这个数字出现重复
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
for(dw=0;dw<bufcount;dw++)
{
if(!(repmarks[dw>>3] & bitmarks[dw&7]))//非重复的位置
{
count2 ++; //只出现一次的数字的数量
}
}
return count2;
}
3. 把数组里面的数字分两类,正数负数,marks数组分成两部分标志,1.该数已经标志[0 --> 2^28-1] 2.标识该数已经重复[2^28 -->2^29-1]。
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//重复出现的数字的个数,例子:1 2 2 3 5 3 4 算2个
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(pBuf[dw]>=0)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
if(marks[2^28+pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}else
{
marks[2^28+pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现重复
count2 ++;
}
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
}
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(pBuf[dw]<0)
{
pBuf[dw] = -pBuf[dw];
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
if(marks[2^28+pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}else
{
marks[2^28+pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现重复
count2 ++;
}
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
}
return count-count2;
}
问题描述如下:
有2.5亿个整数(这2.5亿个整数存储在一个数组里面,至于数组是放在外存还是内存,没有进一步具体说明);
要求找出这2.5亿个数字里面,不重复的数字的个数(那些只出现一次的数字的数目);
另外,可用的内存限定为600M;
要求算法尽量高效,最优;
1. caoxic的算法
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
BYTE repmarks[2^25];//32M 32M*8>2.5亿 //标志2.5亿个数字数组里面的数字是否重复过
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//重复出现的数字的个数,例子:1 2 2 3 5 3 4 算2个
memset(marks,0,sizeof(marks));
memset(repmarks,0,sizeof(repmarks));
ASSERT(sizeof(repmarks)*8>=bufcount);//断言repmarks数组够用
for(dw=0;dw<bufcount;dw++)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
repmarks[dw>>3] |= bitmarks[dw&7];//标志pBuf[dw]这个数字出现重复
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(repmarks[dw>>3] & bitmarks[dw&7])//
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}
else
{
count2 ++; //重复的数字的数量
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];
}
}
}
return count-count2;
}
2. 改一下,应该也可以:
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
BYTE repmarks[2^25];//32M 32M*8>2.5亿 //标志2.5亿个数字数组里面的数字是否重复过
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//只出现一次数字的个数,例子:1 2 2 3 5 3 4 算3个
memset(marks,0,sizeof(marks));
memset(repmarks,0,sizeof(repmarks));
ASSERT(sizeof(repmarks)*8>=bufcount);//断言repmarks数组够用
for(dw=0;dw<bufcount;dw++)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
repmarks[dw>>3] |= bitmarks[dw&7];//标志pBuf[dw]这个数字出现重复
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
for(dw=0;dw<bufcount;dw++)
{
if(!(repmarks[dw>>3] & bitmarks[dw&7]))//非重复的位置
{
count2 ++; //只出现一次的数字的数量
}
}
return count2;
}
3. 把数组里面的数字分两类,正数负数,marks数组分成两部分标志,1.该数已经标志[0 --> 2^28-1] 2.标识该数已经重复[2^28 -->2^29-1]。
BYTE marks[2^29];//512M // BYTE marks[2^32/8]; //用这个就更清楚了,标志所有整数(2^32)出现的可能
const BYTE bitmarks[8]={1,2,4,8,16,32,64,128};
DWORD CalcDifNum(DWORD *pBuf,DWORD bufcount)
{
DWORD dw ;
DWORD count = 0 ;// 不重复的数字(包括出现多次的数字,只算一个)的个数,例子:1 2 2 3 5 3 4 算5个
DWORD count2 = 0 ;//重复出现的数字的个数,例子:1 2 2 3 5 3 4 算2个
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(pBuf[dw]>=0)
{
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
if(marks[2^28+pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}else
{
marks[2^28+pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现重复
count2 ++;
}
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
}
memset(marks,0,sizeof(marks));
for(dw=0;dw<bufcount;dw++)
{
if(pBuf[dw]<0)
{
pBuf[dw] = -pBuf[dw];
if(marks[pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
if(marks[2^28+pBuf[dw]>>3]&bitmarks[pBuf[dw]&7])
{
}else
{
marks[2^28+pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现重复
count2 ++;
}
}
else
{
count ++;
marks[pBuf[dw]>>3] |= bitmarks[pBuf[dw]&7];//标志pBuf[dw]这个数字出现
}
}
}
return count-count2;
}
相关文章推荐
- 问题描述如下: 有2.5亿个整数(这2.5亿个整数存储在一个数组里面,至于数组是放在外存还是内存,没有进一步具体说明); 要求找出这2.5亿个数字里面,不重复的数字的个数; 另外,可用的内存限定为600M; 要求算法尽量高效,最优;
- 从2.5亿个数字里面找出不重复的数字的个数
- 软件开发者面试百问-----有一个数组,里面是从1到1,000,000的整数,其中有一个数字出现了两次,你怎么找出那个重复的数字?
- 计数排序——有一个数组,里面是从1到1,000,000的整数,其中有一个数字出现了两次,你怎么找出那个重复的数字?
- 面试题:如何从三亿个整数里面找出不重复的数字的个数
- 找出第一个重复的数字
- 《剑指offer》-请找出数组中任意一个重复的数字
- 找出重复的那个数字的异或算法
- Java如何找出数组中重复的数字
- 找出数组中重复的数字
- 讲两个int 数组找出重复的数字 用最少的循环
- Java实现找出数组中重复的数字
- 运用bitmap解决一道海量数据处理面试题:在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数。
- 找出所有六位数的平方数中未出现与原数中重复数字的所有数
- C++找出数组中重复的数字( 剑指offer面试题3-1)
- 在2.5亿个整数中找出不重复的整数的C++实现源代码
- 面试题(四)不修改数组找出重复的数字
- 2.5亿个整数中找出不重复的整数
- 找出数组中重复的数字
- 算法-在1001个整数中找出一个重复出现的数字