1. 程式人生 > >【演算法-點陣圖法】在海量資料中查詢重複元素

【演算法-點陣圖法】在海量資料中查詢重複元素

什麼是點陣圖法?

舉個簡單例子,在java中一個int型別的數有32位,而這32只表示一個數太過浪費,於是就考慮讓這32位可以表示32個數,每一位表示該數是否存在,例如:

這裡用16位的二進位制就能表示十六個數字,1表示存在,0表示不存在,上圖就表示存在(16,12,6,4,1)這五個數。

在海量資料中查詢重複出現的元素或者去除重複出現的元素也是常考的問題。針對此類問題,一般可以通過點陣圖法實現,例如,已知某個檔案內包含一些電話號碼,每個號碼為8位數字,統計不同號碼的個數。

本題最好的解決辦法就是通過點陣圖法來實現。

解題思路:

8位整數可以表示的最大十進位制數值為99999999,如果每個數字對應於點陣圖中的一個bit位,那麼儲存八位整數需要99999999bit大約99Mbit,因為1Byte=8bit,所以99Mbit摺合成記憶體為99/8=12.375MB的記憶體,及可以只用12.375MB的記憶體表示所有的8位數電話號碼的內容。

程式程式碼如下:

import java.util.Random;
public class DuplicateTelephone{
	int randNum=100;
	int min=10000000;
	int max=99999999;
	int len=(max-min+1);
	int bit_per_word=32;
	
	int  word_offset(int b){
		return b/bit_per_word;
	}
	int bit_offset(int b){
		return b%bit_per_word;
	}
	void setBit(int[] words,int n){
		int temp=n;
		temp-=min;
		words[word_offset(temp)]|=(1<<bit_offset(temp));
	}
	void clearBit(int[] words,int n){
		words[word_offset(n)]&=~(1<<bit_offset(n));
	}
	boolean getBit(int[] words,int n){
		int result=words[word_offset(n)]&(1<<bit_offset(n));
		return result!=0;
	}
	public void sort(){
		int arr[]=new int[randNum];
		System.out.println("陣列大小:"+randNum);
		int[] words=new int[len/bit_per_word+1];
		int count=0;
		Random r=new Random();
		for(int j=0;j<randNum;j++){
			arr[j]=r.nextInt(len);
			arr[j]+=min;
			System.out.print(arr[j]+" ");
		}
		System.out.println();
		for(int j=0;j<randNum;j++){
			setBit(words,arr[j]);
		}
		System.out.println("排序後a為:");
		for(int i=0;i<len;i++){
			if(getBit(words,i)){
				System.out.print(i+min+" ");
				count++;
			}
		}
		System.out.println();
		System.out.println("總個數為:"+count);
		
	}
	public static void main(String[] args){
		new DuplicateTelephone().sort();
	}
	
}

執行的結果為:

陣列大小:100
46875852 63059260 46888254 54260213 84901496 58876931 28753082 72176161 30014077 84850078 31950213 14204495 26230245 27850510 32455193 68366470 52371514 87138574 94489525 45678876 90450237 42341450 24655913 43282877 49446847 42320941 84516417 35313419 59903775 35761368 11337291 46450272 93115232 55490862 11998766 73065445 47942924 18581547 58818184 77268172 99380374 80558928 16202169 95248485 20644397 34063612 20913170 94324174 67502076 80090509 45820098 81312556 32858162 16476350 15080157 45289864 99027018 87240729 89981567 52198533 39085177 76494986 65134775 93827194 13834939 71752586 32473580 67759555 29073921 72452538 98008564 58115033 64844962 59371680 86529508 69079674 61521841 96326355 25073903 19962950 33966761 83534685 38855968 14084970 85023410 78286139 81124660 48083315 57208466 72108161 26193937 67771844 22611251 51376666 43171943 82768547 47796300 19563949 91347170 47639405
排序後a為:
11337291 11998766 13834939 14084970 14204495 15080157 16202169 16476350 18581547 19563949 19962950 20644397 20913170 22611251 24655913 25073903 26193937 26230245 27850510 28753082 29073921 30014077 31950213 32455193 32473580 32858162 33966761 34063612 35313419 35761368 38855968 39085177 42320941 42341450 43171943 43282877 45289864 45678876 45820098 46450272 46875852 46888254 47639405 47796300 47942924 48083315 49446847 51376666 52198533 52371514 54260213 55490862 57208466 58115033 58818184 58876931 59371680 59903775 61521841 63059260 64844962 65134775 67502076 67759555 67771844 68366470 69079674 71752586 72108161 72176161 72452538 73065445 76494986 77268172 78286139 80090509 80558928 81124660 81312556 82768547 83534685 84516417 84850078 84901496 85023410 86529508 87138574 87240729 89981567 90450237 91347170 93115232 93827194 94324174 94489525 95248485 96326355 98008564 99027018 99380374
總個數為:100