給定一個輸入文件,包含40億個非負整數。產生一個不在該文件中的整數。內存限制:1GB

/**
 * 功能:給定一個輸入文件,包含40億個非負整數。產生一個不在該文件中的整數。內存限制:1GB
 * 進階:內存限制10MB。java

 */數組

 

 

[java] view plain copyapp

 

  1. /** 
  2.  * 思路: 
  3.  *  
  4.  * 1)建立包含40個億個比特的位向量。 
  5.  *     位向量(BV,bit vector)其實就是數組,利用整數(或另外一種數據類型)數組緊湊地儲存布爾值。每一個整數可存儲一串32比特或布爾值。 
  6.  * 2)將BV的全部元素初始化爲0. 
  7.  * 3)掃描文件中的全部數字(num),並調用BV.set(num,1)。 
  8.  * 4)接着,再次從索引0開始掃描BV。 
  9.  * 5)返回第一個值爲0的索引。 
  10.  *  
  11.  *  
  12.  * 值的肯定: 
  13.  * 1)2^32——>40億個不一樣的整數,一個整數4個字節。 
  14.  * 2)2^30字節——>1GB——>2^33bit——>80億比特位。每一位映射一個不一樣的整數,能夠存儲之多80億個不一樣的整數。 
  15.  */  
  16. long numberOfInts=((long)Integer.MAX_VALUE)+1;  
  17. byte[] bitfield=new byte[(int) (numberOfInts/8)];  
  18.   
  19. public void findOpenNumber() throws FileNotFoundException{  
  20.     Scanner in=new Scanner(new FileReader("f:\\file.txt"));  
  21.       
  22.     while(in.hasNext()){  
  23.         int n=in.nextInt();  
  24.         /* 
  25.          *  使用OR操做符設置一個字節的第n位,找出bitfield中相對應的數字。 
  26.          * (例如,10(十進制)將對應於字節數組中索引2的第2位) 
  27.          */  
  28.         bitfield[n/8]=(byte) (1<<(n%8));  
  29.     }  
  30.       
  31.     for(int i=0;i<bitfield.length;i++){  
  32.         for(int j=0;j<8;j++){  
  33.             /* 
  34.              * 取回每一個字節的各個比特。當發現某個比特爲0時,即找到相對應的值。 
  35.              */  
  36.             if((bitfield[i]&(1<<j))==0){  
  37.                 System.out.println(i*8+j);  
  38.                 return;  
  39.             }  
  40.         }  
  41.     }  
  42. }  

 

 

進階:10MBspa

 

[java] view plain copy.net

 

  1. /** 
  2.  * 思路:對數據集進行兩次掃描,就能夠找出不在文件中的整數。能夠將所有整數劃分爲同等大小的區塊。 
  3.  * 第一次掃描數組:肯定每一個數組的元素個數。 
  4.  * 第二次掃描位向量:肯定該範圍內少的數字。 
  5.  *  
  6.  * bitSize::第一次掃描時每一個塊範圍的大小。 
  7.  * blockNum:第一次掃描時塊的個數。 
  8.  *  
  9.  * 值的肯定: 
  10.  * 1)10MB——>2^23Byte。一個整數4個字節,所以,最多包含2^21個元素的數組。 
  11.  * 2)bitSize=(2^32/blockNum)<=2^21,因此,blockNum>=2^11。 
  12.  * 2^11<=bitSize<=2^26。 
  13.  * 在這些條件下,挑選出越靠中間的值,那麼,在任什麼時候候所訴的內存就越少。 
  14.  */  
  15.   
  16. int bitSize=1048576;  
  17. int blockNum=4096;  
  18.   
  19. byte[] bitfield2=new byte[bitSize/8];  
  20. int[] blocks=new int[blockNum];  
  21.   
  22. public void findOpenNumber2() throws FileNotFoundException{  
  23.     Scanner in=new Scanner(new FileReader("f:\\file.txt"));  
  24.       
  25.     int starting=-1;  
  26.     while(in.hasNext()){  
  27.         int n=in.nextInt();  
  28.         blocks[n/bitfield2.length*8]++;  
  29.     }  
  30.       
  31.     for(int i=0;i<blocks.length;i++){  
  32.         /* 
  33.          * 若小於,則說明該塊中至少少了一個數字 
  34.          */  
  35.         if(blocks[i]<bitfield2.length*8){  
  36.             starting=i*bitfield2.length*8;  
  37.             break;  
  38.         }  
  39.     }  
  40.       
  41.     in =new Scanner(new FileReader("f:\\file.txt"));  
  42.     while(in.hasNext()){  
  43.         int n=in.nextInt();  
  44.         if(n>=starting&&n<starting+bitfield2.length*8){  
  45.             bitfield2[(n-starting)/8]=(byte) (1<<((n-starting)%8));  
  46.         }  
  47.     }  
  48.       
  49.     for(int i=0;i<bitfield2.length;i++){  
  50.         for(int j=0;j<8;j++){  
  51.             /* 
  52.              * 取回每一個字節的各個比特。當發現某個比特爲0時,即找到相對應的值。 
  53.              */  
  54.             if((bitfield2[i]&(1<<j))==0){  
  55.                 System.out.println(i*8+j+starting);  
  56.                 return;  
  57.             }  
  58.         }  
  59.     }  
  60.       
相關文章
相關標籤/搜索