java bitmap jar_Java面試中常用的BitMap代碼

引言

阿里內推面試的時候被考了一道編程題:10億個范圍為1~2048的整數,將其去重并計算數字數目。

我看到這個題目就想起來了《編程珠璣》第一章講的叫做BitMap的數據結構,但是我并沒有在java上實現過,這就比較尷尬了,再加上時間不多了,只好暫時用byte代替bit,浪費7個字節,在這篇文章里總結一下BitMap的常用代碼,以免重蹈覆轍。

偷懶的方法

其實java.util包中已經有了一個實現,可以用這個數據結構偷懶,寫了一個Demo如下:

package org.du.offerproblem.bitmap;

import java.util.BitSet;

/**

* Created by 燃燒杯 on 2018/2/24.

*/

public class BitSetTest {

public static void main(String[] args) {

int [] array = new int [] {1,2,3,22,0,3,63};

BitSet bitSet = new BitSet(1);

System.out.println(bitSet.size()); //64

bitSet = new BitSet(65);

System.out.println(bitSet.size()); //128

bitSet = new BitSet(23);

System.out.println(bitSet.size()); //64

//將數組內容組bitmap

for(int i=0;i

{

bitSet.set(array[i], true);

}

System.out.println(bitSet.get(22));

System.out.println(bitSet.get(60));

System.out.println("下面開始遍歷BitSet:");

for ( int i = 0; i < bitSet.size(); i++ ){

System.out.println(bitSet.get(i));

}

}

}

java.util.BitSet的底層是long數組,.size()方法返回的是BitSet當前位數,因為long是64位的,所以size返回的值也是64的整數倍,所以在上面的代碼中發現,我在構造函數中傳入初始化長度1~64中的任意一個值,size的大小都是64位,因為此時long數組的長度只有1,而我一旦將其設置成65,size的大小就變成128了。

用這個類是個偷懶的好辦法,但是一旦面試官一定要讓你自己實現一個就不行了。

自己實現BitMap

可以用int數組來實現一個BitMap,這種方法最關鍵的是求出index在int數組中的位置以及在該位置上的偏移量,有如下公式:

int數組中的位置(belowIndex) = (index - 1) >> 5

偏移量(offset) = (index - 1) & 31

我們這里假設index是從1開始的,所以先將index減去1,如果你要統計的數據范圍是從0開始的,則不需要減去這個1。右移5位(相當于除以32)的原因是,一個int型數據是32位的(2的5次方等于32)。偏移量中&31相當于模32,其原因也因為int型數據是32位的。如果你不準備基于int,而是準備基于其他的,如byte,long的話,(以byte為例)則將>>5改成>>3,&31改成&7即可。

setBit的流程如下:

求出belowIndex并且得到int值;

求出offset并且利用“或運算”將剛才得到的int值的offset位置置為1;

getBit的流程如下:

求出belowIndex并且得到int值;

求出offset,之后利用“與運算”取出offset位置的值將其變為01后返回;

代碼如下:

package org.du.offerproblem.bitmap;

/**

* 實現BitMap

*注:這個bitMap的index是從1開始的

*/

public class BitMap {

private long length;

private static int[] bitsMap;

//構造函數中傳入數據中的最大值

public BitMap(long length) {

this.length = length;

// 根據長度算出,所需數組大小

bitsMap = new int[(int) (length >> 5) + ((length & 31) > 0 ? 1 : 0)];

}

public int getBit(long index) {

int intData = bitsMap[(int) ((index - 1) >> 5)];

int offset = (int) ((index - 1) & 31);

return intData >> offset & 0x01;

}

public void setBit(long index) {

// 求出該index - 1所在bitMap的下標

int belowIndex = (int) ((index - 1) >> 5);

// 求出該值的偏移量(求余)

int offset = (int) ((index - 1) & 31);

int inData = bitsMap[belowIndex];

bitsMap[belowIndex] = inData | (0x01 << offset);

}

public static void main(String[] args) {

BitMap bitMap = new BitMap(32);

bitMap.setBit(32);

System.out.println(bitMap.getBit(1));

System.out.println(bitMap.getBit(32));

}

}

使用BitMap進行數據去重

下面給出數組去重的代碼:

package org.du.offerproblem.bitmap;

import java.util.Arrays;

/**

* Created by 燃燒杯 on 2018/2/24.

* 這個BitMap的去重是從0開始

*/

public class BitMapRepRemove {

//public static final int _1MB = 1024 * 1024;

//public static byte[] flags = new byte[ 512 * _1MB ];

public static byte[] flags;

public static void main(String[] args) {

int[] array = {255, 1024, 1024, 0, 65536, 0, 1024, 8888, 9999, 1111, 8888};

int length = 65536 + 1;

flags = new byte[(int) (length >> 3) + ((length & 7) > 0 ? 1 : 0)];

int index = 0;

for(int num : array) {

if( getFlags(num) != 1) {

//未出現的元素

array[index] = num;

index = index + 1;

//設置標志位

setFlags(num);

}

}

array = Arrays.copyOf(array, index);

System.out.println(Arrays.toString(array));

System.out.println(array.length);

}

public static void setFlags(int num) {

int offset = num & (0x07);

flags[num >> 3] |= 0x01 << offset;

}

public static int getFlags(int num) {

int offset = num & (0x07);

return flags[num >> 3] >> offset & 0x01;

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/395804.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395804.shtml
英文地址,請注明出處:http://en.pswp.cn/news/395804.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

移動端工程架構與后端工程架構的思想摩擦之旅(1)

此文已由作者黎星授權網易云社區發布。歡迎訪問網易云社區&#xff0c;了解更多網易技術產品運營經驗記資源投放后端工程的架構調整與優化 架構思考一直以來對軟件工程架構有著極大的興趣&#xff0c;無論是之前負責的移動端Android工程&#xff0c;亦或是現在轉到后端開發后維…

View野指針問題分析報告

【問題描述】 音樂組同事反饋了一個必現Native Crash問題&#xff0c;tombstone如下&#xff1a; pid: 5028, tid: 5028, name: com.miui.player >>> com.miui.player <<< signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 79801f28r0 7ac59c98 r1 …

SicilyFunny Game

一、題目描述 Two players, Singa and Suny, play, starting with two natural numbers. Singa, the first player, subtracts any positive multiple of the lesser of the two numbers from the greater of the two numbers, provided that the resulting number must be non…

java 分布式同步_Java Web分布式集群搭建(三)——Session同步

對于一個業務系統的Tomcat集群來說&#xff0c;必須保證同一個用戶訪問到任一臺服務器上都可以維持之前操作的身份。比如在服務器A進行了登陸&#xff0c;那么在服務器B中也要同步該用戶已登錄的狀態&#xff0c;這里就用到了Session的同步。同步方式sticky模式、復制模式、Ter…

移動應用程序和網頁應用程序_如何不完全破壞您的移動應用程序的用戶界面

移動應用程序和網頁應用程序by Luke Konior盧克科尼爾(Luke Konior) 如何不完全破壞您的移動應用程序的用戶界面 (How to not utterly ruin your mobile app’s user interface) There’s no single universal formula for designing a great user interface (if you discover…

logging記錄日志

日志是一個系統的重要組成部分&#xff0c;用以記錄用戶操作、系統運行狀態和錯誤信息。日志記錄的好壞直接關系到系統出現問題時定位的速度。logging模塊Python2.3版本開始成為Python標準庫的一部分。 日志級別 在最簡單的使用中&#xff0c;我們直接導入logging模塊&#xff…

C#編程之接口

1.定義 接口是把公共方法和屬性組合起來&#xff0c;以封裝特定功能的一個集合。&#xff08;一旦定義了接口&#xff0c;就可以在類中實現它。這樣類就可以支持接口所指定的所有屬性和成員&#xff09; 注意1&#xff1a;接口不能單獨存在。不能像實例化一個類那樣實例化一個接…

supervisor守護進程

2019獨角獸企業重金招聘Python工程師標準>>> supervisor 是一個client/server系統,把不是守護進程的進程變成守護進程,并監控和控制類 Unix 操作系統上的進程。 upervisor就是用Python開發的一套通用的進程管理程序&#xff0c;能將一個普通的命令行進程變為后臺dae…

神經網絡算法 java 源代碼_神經網絡算法與實現 ——基于Java語言 代碼實例

【實例簡介】Neural Network Programming with Java_ISBN 978-7-115-46093-6【實例截圖】【核心代碼】NeuralNetworkProgrammingwithJava_code└── Neural Network Programming with Java_code├── Chapter1│ ├── HiddenLayer.java│ ├── InputLayer.java│ ├…

javascript面試_在編碼面試中需要注意的3個JavaScript問題

javascript面試JavaScript is the official language of all modern web browsers. As such, JavaScript questions come up in all sorts of developer interviews.JavaScript是所有現代Web瀏覽器的官方語言。 因此&#xff0c;各種開發人員訪談中都會出現JavaScript問題。 T…

【學習筆記】深入理解js原型和閉包(11)——執行上下文棧

繼續上文的內容。 執行全局代碼時&#xff0c;會產生一個執行上下文環境&#xff0c;每次調用函數都又會產生執行上下文環境。當函數調用完成時&#xff0c;這個上下文環境以及其中的數據都會被消除&#xff0c;再重新回到全局上下文環境。處于活動狀態的執行上下文環境只有一個…

Java基礎--訪問權限控制符

今天我們來探討一下訪問權限控制符。 使用場景一&#xff1a;攻城獅A編寫了ClassA&#xff0c;但是他不想所有的攻城獅都可以使用該類&#xff0c;應該怎么辦&#xff1f; 使用場景二&#xff1a;攻城獅A編寫了ClassA&#xff0c;里面有func1方法和func2方法&#xff0c;但是他…

css繪制正方體_設計師僅使用CSS繪制了8個標志性X戰警

css繪制正方體Here are three links worth your time:這是三個值得您花費時間的鏈接&#xff1a; A designer drew 8 iconic X-Men using nothing but CSS (1 minute interactive) 一位設計師僅用CSS繪制了8個標志性的X戰警( 互動時間為1分鐘 ) Raspberry Pi just turned 5. H…

Dubbo簡單介紹及實例

1、概念 Dubbo是一個分布式服務框架&#xff0c;以及阿里巴巴內部的SOA服務化治理方案的核心框架。其功能主要包含&#xff1a;高性能NIO通訊及多協議集成。服務動態尋址與路由。軟負載均衡與容錯&#xff0c;依賴分析與降級等。 說通俗點&#xff0c;就是首先將程序組件化成一…

Oracle 10.2.0.5升級至11.2.0.4

參照MOS 官方文檔Complete Checklist for Manual Upgrade to Oracle Database 11gR2 (11.2) (Doc ID 837570.1)一、升級前的準備1、復制utlu112i.sql腳本從11G數據庫復制$ORACLE_HOME/rdbms/admin/utlu112i.sql 腳本至10g 數據庫臨時目錄&#xff0c;準備執行如果不在10g數據庫…

脫殼_詳細_使用的方法_01

ZC: 如何確定被調試程序已經來到了 未加殼的程序中&#xff1f; ZC:  視頻中是使用判斷集中語言的特征 ZC:  我的方法&#xff1a;上面的方式 ESP平衡 1、第1課 (1)、單步跟蹤&#xff08;原則&#xff1a;向下的跳轉>正常F8&#xff0c;向上的跳轉>F4跳過(或者用F2…

android 函數式編程_Android開發人員的函數式編程-第1部分

android 函數式編程by Anup Cowkur通過安納普考庫(Anup Cowkur) Android開發人員的函數式編程-第1部分 (Functional Programming for Android Developers — Part 1) Lately, I’ve been spending a lot of time learning Elixir, an awesome functional programming language…

java編程 內存_Java編程技術之淺析JVM內存

JVMJVM->Java Virtual Machine:Java虛擬機,是一種用于計算設備的規范&#xff0c;它是一個虛構出來的計算機&#xff0c;是通過在實際的計算機上仿真模擬各種計算機功能來實現的。基本認知&#xff1a;1.JVM是用于運行Java代碼的假象計算機&#xff0c;主要有一套字節碼指令…

bzoj1116: [POI2008]CLO

傳送門&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id1116 題目大意&#xff1a;Byteotia城市有n個 towns m條雙向roads. 每條 road 連接 兩個不同的 towns ,沒有重復的road. 你要把其中一些road變成單向邊使得&#xff1a;每個town都有且只有一個入度 題解&am…

java排序算法大全_各種排序算法的分析及java實現

排序一直以來都是讓我很頭疼的事&#xff0c;以前上《數據結構》打醬油去了&#xff0c;整個學期下來才勉強能寫出個冒泡排序。由于要找工作了&#xff0c;也知道排序算法的重要性(據說是面試必問的知識點)&#xff0c;所以又花了點時間重新研究了一下。排序大的分類可以分為兩…