书中提到了产生大量不重复数据的需要:
产生NUM个N内的32位数字
上述位图标识采用的是才用开辟一定int型数组使用的,其中BITSPERWORD=32.
其中,在数据产生达到千万以上或是N和NUM相差不多,第一种策略会是机器跑个没停,所以,使用了就近原则,以使尽快找到不重复数据。
当然,我们还可以使用vs2008中stl中的位图数据类型,需包含头文件:
位图的使用:
然后,排序的方法与上述位图思路相同,(毕竟,没法一下对这么多数字一起处理,故应一个个从磁盘读取,标识,然后再读取数据)。
不过,当数据很大时,效率还是很低的,例如:
当产生亿计的数据,需要花费大概5~6小时。
如果要产生第二章所需的2^32内40亿个数据,时间可想而知。
另外,在数据排序的时候,如果内存有限制,比如只有几M字节使用,而上述产生2^32数据量时需开辟512M空间,即使亿计的数据量,也要仅百M的空间,如此我们需要采用通道技术。
K通道在Kn时间和n/k空间内排序:
将数据分为几个部分,分别读取磁盘,每次访问一定大小范围的数据,最终标记完所有数据。
产生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空间内排序:
将数据分为几个部分,分别读取磁盘,每次访问一定大小范围的数据,最终标记完所有数据。