位图排序-有重复元素

之前讨论的位图排序有一个限制条件:所排序的整数没有重复项。这里根据《编程珠玑》上所讲,实现了一种允许出现重复项的位图排序,但是这种排序仍然有限制:最多允许重复次数。

问题描述:

给定输入文件,文件中每条记录是一个整型数(每个数据最多允许重复10次),每条记录最大为n,n<=10000000,要求对文件中所有记录排序(从小到大),然后输入到给定文件。

分析:

既然每个数据项最多允许重复10次,那么用1个bit位表示一个整数就不行了,至少需要4个bit位。于是每个整数(假设为32位)可以表示8个数据项。实现时同样需要找到每个数据项在数组中的下标label和在对应下标数据的“位”偏移量pos。

set_add实现为一个数据项添加出现次数,实现方式为:首先根据label和pos找到表示当前数据项的4个bit位,然后将这4个bit位转换成一个整数tmp(出现的次数),让tmp++,最后将tmp写回当前数据项的bit位(对原来的bit位先清除,然后覆盖)。

clear实现清除当前数据项对应的bit位。

test返回当前数据项的出现次数。

C++实现如下:

1 #include 2 #include 3 using namespace std; 4 const int MAX = 40000; 5 const int BITSPERWORD = 32; 6 const int NUM = 4*MAX/BITSPERWORD; 7 int a[NUM+1]; 8 9 void set_add(int i) 10 { 11 int label = i>>3; 12 int pos = i*4%32; 13 14 int tmp = (a[label]>>pos)&0x0f; 15 tmp++; 16 a[label]&=~(0x0f<>3; 22 int pos = i*4%32; 23 24 a[label]&=~(0x0f<>3; 29 int pos = i*4%32; 30 int tmp = (a[label]>>pos)&0x0f; 31 return tmp; 32 } 33 int main() 34 { 35 ifstream fin("source.file"); 36 ofstream fout("sort.file"); 37 int tmp; 38 int i = 0; 39 for(i=1;i>tmp) 42 { 43 set_add(tmp); 44 } 45 for(i=1;i

你可能感兴趣的:(初识算法)