位图排序-有重复元素 收藏

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

问题描述:

给定输入文件,文件中每条记录是一个整型数(每个数据最多允许重复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++实现如下:

view plaincopy to clipboardprint?
1 #include <iostream>
2 #include <fstream>
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<<pos);
17 a[label] += tmp<<pos;
18 }
19 void clear(int i)
20 {
21 int label = i>>3;
22 int pos = i*4%32;
23
24 a[label]&=~(0x0f<<pos);
25 }
26 int test(int i)
27 {
28 int label = i>>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<MAX+1;i++)
40 clear(i);
41 while(fin>>tmp)
42 {
43 set_add(tmp);
44 }
45 for(i=1;i<MAX+1;i++)
46 {
47 tmp = test(i);
48 cout << tmp << endl;
49 for(int j = 1;j<=tmp;j++)
50 fout << i << endl;
51 }
52 }


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/clearriver/archive/2009/07/19/4361941.aspx

你可能感兴趣的:(排序)