大數據之排序

例如:假設要對8億個正整數進行排序(000000000-999999999),該如何操作?

分析:首先,確認這些數是不是不重複的,這點很重要,8億個9整數佔用內存很龐大,用計算機直接一次性進行處理顯然不現實,800,000,000*4Byte=3.0G。爲此可以利用Bloom Filter建立N個哈希函數的映射集;或者使用導入數據庫的方法;還可以使用bit位的方法......

1、分段排序

由於這8億個數是在數據段000000000-999999999內的,因此可能的數一共有10億個,3.8G空間完全可以足夠,爲此可以將該數據段分爲000000000-099999999、100000000-199999999、......、900000000-999999999共10段,對8億個整數依次搜索位於每一段的數並提取到內存進行排序,然後輸出,每段爲372M,完全在Win32的處理能力內,如是進行10次,並將結果連接起來即可。

由於分段的原因,導致要對許多數字進行多次搜索,例如,如果按分段從前往後的順序依次搜索讀入內存的話,位於最後一段內(即900000000-999999999)的數要被搜索10次,往前依次類推,因此如果該數均勻分佈的話,平均要被搜索5.5次,嚴重影響速度和效率。

2、導入數據庫

可以利用現成的數據庫進行數據的導入,並進行排序,該方法操作簡單,但是要用到數據庫設備,成本增加。

3、bit位方法

由於這8億個數位於000000000-999999999範圍內,爲此可以建立一個10位的二進制數組或空間,對應位置的下標分別爲000000000-999999999,則佔用內存約爲120M,完全位於系統處理能力內。爲此,先將10億位全部置爲0,依次讀入8億個數,將該位置的bit值置爲1,直至結束,則得到一個8億位置爲1的10億數組。將該數組中bit位爲1的下標值依次輸出到文件,即得到排序結果。該方法,佔用內存小,讀取次數少,處理速度相對快。

可以將數據文件分別讀入,讀入一段的代碼如下:

 

  1. #include <iostream>  
  2. #include <fstream>  
  3. #include <bitset>  
  4. #include <string>  
  5.  
  6. using namespace std;  
  7.  
  8. int CountLines(char *filename)//獲取文件的行數  
  9. {  
  10.     ifstream ReadFile;  
  11.     int n = 0;  
  12.     string temp;  
  13.     ReadFiles.open(filename.ios::in);//ios::in表示以只讀的方式讀入讀取文件  
  14.     if(ReadFile.fail())  
  15.     {  
  16.         return 0;  
  17.     }//if  
  18.     else{  
  19.         while(getline(ReadFile,temp))  
  20.         {  
  21.             n++;  
  22.         }//while  
  23.         return n;  
  24.     }//else  
  25.     ReadFile.close();  
  26. }//CountLines  
  27.  
  28. void input(){  
  29.     ifstream file;  
  30.     int LINES;  
  31.     int *tc = new int[LINES];  
  32.     bitset <1000000000> address;  
  33.     cout<<"請輸入要打開的文件名:"<<endl;  
  34.     cin>>filename;  
  35.     file.open(filename,ios::in);  
  36.     if(file.fail()){  
  37.         cout<<"文件不存在!"<<endl;  
  38.         file.close();  
  39.         cin.get();  
  40.     }else{  
  41.         LINES=CoutnLines(filename);  
  42.         int *tc = new int[LINES];  
  43.         int i = 0;  
  44.         while(!file.eof()){//讀取數據到數組  
  45.             file>>tc[i];  
  46.             address.set(tc[i]);  
  47.             ++i;  
  48.         }  
  49.         file.close();  
  50.     }  
  51. }  

依次將文件讀入後,最後得到結果,一次性輸出:

 

  1. ofstream in;  
  2. in.open("result.txt",ios::trunc);//ios::trunc表示在打開文件前將文件清空,不存在則創建之  
  3.  
  4. size_t m = address.size();  
  5. for(int j = 0;j! = m;++j)  
  6. if(address.test(j))  
  7.     in<<j<<"\n";  
  8. in.close(); 

排序結束!懇請各位大牛小牛各種牛輕拍指正......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章