现在的位置: 首页 > 综合 > 正文

位图排序 c/c++

2013年10月09日 ⁄ 综合 ⁄ 共 2986字 ⁄ 字号 评论关闭

问题:

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

限制:主存不超过1MB(实际程序超过了1M)。

按照《编程珠玑》上介绍,有以下几种方法:

1,多通道分片读取文件,然后合并排序分片文件

2,位图排序:适合于对大量不重复数据,并且数据其他相关数据。

 

位图排序就是使用一张表来记录关键字的存在状态(存在或不存在),然后通过采集到的状态(在/不在)通过一次遍历来确定序列顺序。

算法描述如下:

示例:对于不超过20的整型数据,可以用20个bit位来表示,例如1,2,4,14可表示:

00000010000000001011,即将每一个数对应的bit位置1。

因此,对于10000000个记录项,可以用10000000个bit位来表示。

在设置或清除每一个读取的整数对应的位时:

(1)首先找到该整数对应的数组的下标(i>>5)。由于数组中的每一个整数有32位(假设int型为32位),这32位可以表示32个整数。

(2)找到该整数在对应整数的位坐标pos。

(3)设置或清除该整数的位。

1 #include <iostream>
2 #include <bitset>
3 #include <fstream>
4 #include <vector>
5 using namespace std;
6 const int BITSPERWORD=32;
7 const int MAX = 100000;
8 const int NUM = MAX/BITSPERWORD;
9 vector< bitset<32> > vec(1+NUM);
10 void set(int i )
11 {
12         /*
13         int tmp = i>>5;
14         cout << tmp <<endl;
15         */
16         vector<bitset<32> >::iterator it = vec.begin();
17         int pos = i%32;
18         it += i>>5;
19         (*it).set(pos,1);
20 }
21 void clear(int i)
22 {
23         vector<bitset<32> >::iterator it = vec.begin();
24         int pos = i%32;
25         it += i>>5;
26         (*it).reset(pos);
27 }
28 int test(int i)
29 {
30         vector<bitset<32> >::iterator it = vec.begin();
31         int pos = i%32;
32         it += i>>5;
33         if((*it).test(pos))
34                 return 1;
35         else
36                 return 0;
37
38 }
39 int main()
40 {
41         ifstream fin("source.file");
42         ofstream fout("sort.file");
43         int i = 0;
44         int tmp = 0;
45
46         vector< bitset<32> >::iterator it = vec.begin();
47         while(it!=vec.end())
48         {
49                 (*it).reset();
50                 //cout << (*it)<<endl;
51                 it++;
52         }
53         /*
54         for(i = 0;i<NUM +1;i++)
55                 clear(i);
56                 */
57         while(fin>>tmp)
58         {
59                 set(tmp);
60         }
61         for(i = 0;i<MAX+1;i++)
62                 if(test(i))
63                         fout<< i << endl;
64 } 

c语言实现如下:
1 #include <stdio.h>
2
3 #define MAX 100000
4 #define BITSPERWORD 32
5 #define NUM (MAX/BITSPERWORD)
6
7 int a[NUM+1];
8 void set(i)
9 {
10         int label;
11         int pos;
12         label = i>>5;
13         pos = i%32;
14 //      pos = i&0x1f;
15         a[label] |= 1<<pos;
16 }
17 void clear(i)
18 {
19         int label;
20         int pos;
21         label = i>>5;
22         pos = i%32;
23         //pos = i&0x1f;
24         a[label] &= ~(i<<pos);
25 }
26 int test(i)
27 {
28         int label;
29         int pos;
30         label = i>>5;
31 //      pos = i&0x1f;
32         pos = i%32;
33
34         if(a[label]&(~(1<<pos)))
35                 return 1;
36         else
37                 return 0;
38 }
39 int main()
40 {
41
42         FILE *fin;
43         FILE *fout;
44         fin =  fopen("source.file","r");
45         fout =  fopen("sort.file","w");
46         int i = 0;
47         for(i = 1;i<MAX+1;i++)
48                 clear(i-1);
49         int tmp;
50         while(fscanf(fin,"%d",&tmp)!=EOF)
51         {
52                 set(tmp-1);
53         }
54         for(i = 1;i<MAX+1;i++)
55         {
56                 if(test(i-1))
57                 {
58                         fprintf(fout,"%d/n",i);
59                 }
60         }
61 }

在我的机器上测试两种语言实现的效率:测试的数据位100000,c++用时为c语言的约两倍。

抱歉!评论已关闭.