《编程珠玑》第一章 位图在大量数据中的使用

书中提到了产生大量不重复数据的需要:
产生NUM个N内的32位数字

for (i = 0;i < NUM;++ i)
{
temp = (double)rand()/(RAND_MAX+1)*N;
bits = temp / BITSPERWORD;
n = temp % BITSPERWORD;
while (a[bits] & (1<<n)) //already existing number
{
//就近选择
if (temp >= N)
{
temp = 0;
}
else
{
temp ++;
}
//下述策略效率太慢
//temp += (double)rand()/(RAND_MAX+1)*N;
//temp %= N;
bits = temp / BITSPERWORD;
n = temp % BITSPERWORD;
}
outfile<<temp<<" ";
a[bits] |= (1<<n); //set to 1
}

上述位图标识采用的是才用开辟一定int型数组使用的,其中BITSPERWORD=32.
其中,在数据产生达到千万以上或是N和NUM相差不多,第一种策略会是机器跑个没停,所以,使用了就近原则,以使尽快找到不重复数据。
当然,我们还可以使用vs2008中stl中的位图数据类型,需包含头文件:

#include <bitset>


位图的使用:

bits.test(pos) //检测是否为一
bits.set(pos) //置1
bits.reset(pos) //置0


然后,排序的方法与上述位图思路相同,(毕竟,没法一下对这么多数字一起处理,故应一个个从磁盘读取,标识,然后再读取数据)。

不过,当数据很大时,效率还是很低的,例如:
当产生亿计的数据,需要花费大概5~6小时。
如果要产生第二章所需的2^32内40亿个数据,时间可想而知。

另外,在数据排序的时候,如果内存有限制,比如只有几M字节使用,而上述产生2^32数据量时需开辟512M空间,即使亿计的数据量,也要仅百M的空间,如此我们需要采用通道技术。
K通道在Kn时间和n/k空间内排序:
将数据分为几个部分,分别读取磁盘,每次访问一定大小范围的数据,最终标记完所有数据。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值