位圖排序

問題:

給定輸入文件,文件中每條記錄是一個整型數(不重複),每條記錄最大爲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語言的約兩倍。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/zhongjiekangping/archive/2010/04/02/5444083.aspx

發佈了20 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章