海量數(shù)據(jù)去重排序bitmap(位圖法)在java中實(shí)現(xiàn)的兩種方法
在海量數(shù)據(jù)中查找出重復(fù)出現(xiàn)的元素或者去除重復(fù)出現(xiàn)的元素是面試中??嫉奈膱D。針對(duì)此類問(wèn)題,可以使用位圖法來(lái)解決。例如:已知某個(gè)文件內(nèi)包含若干個(gè)電話號(hào)碼,要求統(tǒng)計(jì)不同的號(hào)碼的個(gè)數(shù),甚至在O(n)時(shí)間復(fù)雜度內(nèi)對(duì)這些號(hào)碼進(jìn)行排序。
位圖法需要的空間很少(依賴于數(shù)據(jù)分布,但是我們也可以通過(guò)一些放啊發(fā)對(duì)數(shù)據(jù)進(jìn)行處理,使得數(shù)據(jù)變得密集),在數(shù)據(jù)比較密集的時(shí)候效率非常高。例如:8位整數(shù)可以表示的最大十進(jìn)制數(shù)值為99999999,如果每個(gè)數(shù)組對(duì)應(yīng)于一個(gè)bit位,那么把所有的八進(jìn)制整數(shù)存儲(chǔ)起來(lái)只需要:99Mbit = 12.375MB.
實(shí)際上,java jdk1.0已經(jīng)提供了bitmap的實(shí)現(xiàn)BitSet類,不過(guò)其中的某些方法是jdk1.4之后才有的。
下面我先自己實(shí)現(xiàn)一下bitmap 的原理,然后再直接調(diào)用jdk的BitSet類分別實(shí)現(xiàn)bitmap, 方便比較理解:
package swordoffer;
//去除重復(fù)并排序
import java.util.Arrays;
import java.util.BitSet;
import java.util.Random;
/**
* @author Gavenyeah
* @date Time:
* @des:
*/
public class BitMap {
int ARRNUM = 800;
int LEN_INT = 32;
int mmax = 9999;
int mmin = 1000;
int N = mmax - mmin + 1;
public static void main(String args[]) {
new BitMap().findDuplicate();
new BitMap().findDup_jdk();
}
public void findDup_jdk() {
System.out.println("*******調(diào)用JDK中的庫(kù)方法--開(kāi)始********");
BitSet bitArray = new BitSet(N);
int[] array = getArray(ARRNUM);
for (int i = 0; i < ARRNUM; i++) {
bitArray.set(array[i] - mmin);
}
int count = 0;
for (int j = 0; j < bitArray.length(); j++) {
if (bitArray.get(j)) {
System.out.print(j + mmin + " ");
count++;
}
}
System.out.println();
System.out.println("排序后的數(shù)組大小為:" + count );
System.out.println("*******調(diào)用JDK中的庫(kù)方法--結(jié)束********");
}
public void findDuplicate() {
int[] array = getArray(ARRNUM);
int[] bitArray = setBit(array);
printBitArray(bitArray);
}
public void printBitArray(int[] bitArray) {
int count = 0;
for (int i = 0; i < N; i++) {
if (getBit(bitArray, i) != 0) {
count++;
System.out.print(i + mmin + "\t");
}
}
System.out.println();
System.out.println("去重排序后的數(shù)組大小為:" + count);
}
public int getBit(int[] bitArray, int k) {// 1右移 k % 32位 與上 數(shù)組下標(biāo)為 k/32 位置的值
return bitArray[k / LEN_INT] & (1 << (k % LEN_INT));
}
public int[] setBit(int[] array) {// 首先取得數(shù)組位置下標(biāo) i/32, 然后 或上
// 在該位置int類型數(shù)值的bit位:i % 32
int m = array.length;
int bit_arr_len = N / LEN_INT + 1;
int[] bitArray = new int[bit_arr_len];
for (int i = 0; i < m; i++) {
int num = array[i] - mmin;
bitArray[num / LEN_INT] |= (1 << (num % LEN_INT));
}
return bitArray;
}
public int[] getArray(int ARRNUM) {
@SuppressWarnings("unused")
int array1[] = { 1000, 1002, 1032, 1033, 6543, 9999, 1033, 1000 };
int array[] = new int[ARRNUM];
System.out.println("數(shù)組大?。? + ARRNUM);
Random r = new Random();
for (int i = 0; i < ARRNUM; i++) {
array[i] = r.nextInt(N) + mmin;
}
System.out.println(Arrays.toString(array));
return array;
}
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
相關(guān)文章
springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程
這篇文章主要介紹了springboot集成mybatis-maven插件自動(dòng)生成pojo的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Java使用IO流實(shí)現(xiàn)音頻的剪切和拼接
這篇文章主要為大家詳細(xì)介紹了Java使用IO流實(shí)現(xiàn)音頻的剪切和拼接,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
Java中Integer.parseInt和Integer.valueOf區(qū)別小結(jié)
在Java中,Integer.parseInt()和Integer.valueOf()都可以將字符串轉(zhuǎn)換為整數(shù)類型,那么他們有哪些區(qū)別呢,本文就來(lái)詳細(xì)的介紹一下2023-09-09
Springboot 使用maven release插件執(zhí)行版本管理及打包操作
maven-release-plugin 可用于構(gòu)建release版本項(xiàng)目,實(shí)現(xiàn)自動(dòng)打tag、遞增版本號(hào)、分發(fā)release版本jar包至倉(cāng)庫(kù),接下來(lái)通過(guò)本文給大家介紹Springboot 使用maven release插件執(zhí)行版本管理及打包操作,需要的朋友可以參考下2022-03-03
關(guān)于Java Guava ImmutableMap不可變集合源碼分析
這篇文章主要介紹Java Guava不可變集合ImmutableMap的源碼分析的相關(guān)資料,需要的朋友可以參考下面具體的文章內(nèi)容2021-09-09
基于springboot+vue實(shí)現(xiàn)垃圾分類管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于springboot+vue實(shí)現(xiàn)垃圾分類管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07

