程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 對大數據量進行排序--位圖法

對大數據量進行排序--位圖法

編輯:C++入門知識

題目:對2G的數據量進行排序,這是基本要求。 數據:1、每個數據不大於8億;2、數據類型位int;3、每個數據最多重復一次。 內存:最多用200M的內存進行操作。 我聽過很多種類似問題的解法,有的是內存多次利用,有的用到了外存,我覺得這兩種做法都不是比較好的思想,太慢。由於這個題目看起來沒有對效率進行約束,所以這兩種方法也是對的,但是我這次提出一個比較好的算法來解答此題,如果有更好的做法請趕快跟帖留言,共同討論。希望大神們的加入。。。。。 思想:把200M的內存平分,可以開兩個數組,一個數組arr存放一遍不重復的所有數據,另一個數組arr_2只存放重復的數據。存放方法是對數組中的每個數據的位進行操作。比如:18這個數,18/32=0,18就會對應arr[0]這個數組中的某一位,而每一個數組元素都是32位組成,18%32=18,也就是說arr[0]那個數的第18位對應18這個數。同樣道理再來一個數:43    43/32=1,43%32=11,也就是說43對應的是arr[1]中的第11位。只要找到了對應位置,把該位置1,其余位置不變(默認為0),遍歷一次數據,就會把內存中的對應位置1.如果遇到重復數據,此時就會用到第二個數組了,若本次查詢該位已經為1,那麼就要把arr_2這個數組中的對應位置1。在輸出的時候就要同步遍歷兩個數組。 輸出:就是一個反向還原過程,遍歷內存中的每一位,該位對應的有數組下標和所處位,進行一次乘、和運算就能還原回來數據,並依次寫入文件或者打印到屏幕上。 廢話不多說,直接上代碼,如有問題,跟帖討論。 [cpp]   <pre class="cpp" name="code">#include <stdio.h>   #include <stdlib.h>   #define NUM 1024*1024   //數據占用的內存大小,即存儲數據的載體   #define N   1024*1024*128   //10測試正確性可以用10來測    //數據量      unsigned long int arr[NUM];   unsigned long int arr_2[NUM];   unsigned long int temp[N];//本可不必開辟這個數組的,直接從文件中讀取      int main(){              int i,j,temp_num=0,temp_num_2=0,flag=0;        //清空內存      memset(arr,0,sizeof(arr));      memset(arr_2,0,sizeof(arr_2));  </pre><pre class="cpp" name="code"> //得到數據,存到數組中       for(i=0;i<N;i++){           temp[i]=N-i;           temp[i++]=N-i;       }       //下邊這個循環是一個排序過程,把對應位置1,如果原來是1,就把另一塊內存中的對應位置1       for(i=0;i<N;i++){           if(((arr[temp[i]/32] >> (temp[i]%32)) & 0x00000001) == 1)               arr_2[temp[i]/32] |= (0x00000001<<(temp[i]%32));           arr[temp[i]/32] |= (0x00000001<<(temp[i]%32));       }       printf("\n");          for(i=0;i<NUM && flag<N;i++){           if(arr[i] == 0)               continue;           temp_num=arr[i];           for(j=0;j<32;j++){               if((temp_num&0x00000001) == 0){                   temp_num=(temp_num>>1);               }               else if((temp_num&0x0001) == 1){                   printf("%d ",(i<<5)+j);                   temp_num=(temp_num>>1);                   temp_num_2=arr[i];                   flag++;                   //重復數據的輸出                   if((temp_num_2&0x00000001) == 1){                       printf("%d ",(i<<5)+j);                       flag++;                   }                  }           }       }  www.2cto.com     printf("\n");       return 0;   }</pre><br>   <br>   <p></p>   <pre></pre>   <p></p>   <p></p>   <pre></pre>   <p></p>  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved