位操作面試題集錦

來源:互聯網
上載者:User

位操作面試題集錦

都是從網上找的,自己按照參考答案寫了一遍,這裡匯總一下,留著複習。也希望路過的挑刺指正。

左移位:將運算數的二進位碼整體(包括符號位)左移指定位元,左移之後的空位用0補充
右移位:將運算數的二進位碼整體右移指定位元,右移之後的空位用符號位補充(正數用0補充,負數用1補充)

 

1 寫一個BitUtil類,設定0、1經常用到。

public class BitUtil{public static int setBit(int num,int index,boolean b){if(b) return (num | (1<<index));int mask = ~(1<<index);//~ 是按位取反return (num & mask);}public static boolean getBit(int num,int index){int mask = num & (1<<index);return (mask != 0);}}

2 統計一個整數二進位式‘1’的個數

public static void count1(int n){int num=n;int count=0;//解法1:每次右移,和1<<31 & 運算,不為0,則該位是1/**while(num!=0){if((num&(1<<31))!=0) count++;num=(num<<1);}**///解法2: n&(n-1)的效果:n的二進位位從右往左第一個1變成0,該位置右側全部變成1//110100 & 110011 = 110000,這樣每次消掉一個1//-2147483648-1=2147483647 即0x80000000-1=0x7fffffff 二者相&為0while(num!=0){num&=(num-1);System.out.println(num);count++;}System.out.println(n+"有"+count+"個1");}

3 實現方法將一個整數中的偶數位和奇數位交換。(是交換二進位位)   例如:將0位和1位交換,2位和3位交換 

public static void swapOddEven(int num){//注釋的語句方法對於負數不適用,因為負數右移時,用1填充 例如10****,//本來應該變成01****為正數,但是由於用了1填充, | 運算後必然還是負的//所以應該先右移,然後用0把填充的1替換掉//int result = ((0xaaaaaaaa & num)>>1)|((0x55555555 & num)<<1);int result = ((num>>1)&0x55555555)|((0x55555555 & num)<<1);System.out.println(result);}

4給定一個32bit的數值,如果輸出位元位反轉後的值,   如對於4bit的二進位值1011,翻轉後為1101。(第1位放32位,第1位放第32位……,第32位放第一位)
  要求複雜度O(lgn),n 為位元位元。

public static void reversBits(int num){/**土辦法,達不到時間要求for(int i=0;i<32;i++){int result=0;result=((result<<1)|(num&1));num=num>>1;}**//**採用交換的方法,先兩位對調,然後4位…… **/num = ((num>>1)&0x55555555)|((num&0x55555555)<<1);num = ((num>>2)&0x33333333)|((num&0x33333333)<<2);num = ((num>>4)&0x0f0f0f0f)|((num&0x0f0f0f0f)<<4);num = ((num>>8)&0x00ff00ff)|((num&0x00ff00ff)<<8);num = ((num>>16)&0x0000ffff)|((num&0x0000ffff)<<16);System.out.println("result"+num);}

5 實現Function Compute將整數從A變成B需要變動幾位   例如 輸入:31,14 輸出 2

public static void changeA2B(int a,int b){int count=0;/**for(int i=0;i<32;i++){if(BitUtil.getBit(a,i)!=BitUtil.getBit(b,i)) count++;}**///或者使用Xorfor(int c=(a^b);c>0;c=(c>>1)){// c=(c>>1)有沒有簡寫方式?count+=(c&1);}System.out.println("需要改動"+count+"次");}

6  一個數組A[1,n]能容納n個數字,現將0到n這n+1個數字,隨機的放入到數組中。    最後會有一個數字沒有進入數組。現在讓你找出這個數字。   但是有如下的限制,不能直接存取數組的整個元素,只能訪問“A[i]的第j位”。   寫出代碼找出該元素。能否將時間複雜度控制在O(n)。

/**解法1: 借鑒編程珠璣 時間複雜度 n+n/31+31 = O(n)  解法2: 講0~n按照二進位碼錶示,則最低位是0,1,0,1……,如果n奇數count(0)>count(1),n是偶數count(0)=count(1)所以如果確實的數為K:若K的最低位是0 當n為奇數時count(0)=count(1)    當n為偶數時count(0)=count(1)-1若K的最低位是1 當n為奇數時count(0)=count(1)-2    當n為偶數時count(0)=count(1)-1這樣每次可以刪除一半的數,時間複雜度O(n)+O(n/2)+O(n/4)+…… 但是每次都需要講末尾為0、1的數再儲存所以感覺效率不是很好**/public static void findTheMissOne(int [] array){int miss=0;int n = array.length;int memArray [] = new int[(n+30)/31];System.out.println(memArray.length);for(int i=0;i<n;i++){int curr = array[i];memArray[curr/31] = BitUtil.setBit(memArray[curr/31],curr%31,true); //這樣調用setBit總感覺很彆扭}int j=0;for(;j<memArray.length;j++){if( (memArray[j] | (1<<31)) != -1) break;}int k=0;for(;k<31;k++){if(!BitUtil.getBit(memArray[j],k)) break;}miss = j*31+k;System.out.println("the missing num is :"+miss);}

參考網址:

http://blog.csdn.net/coder_xia/article/details/7922077

http://blog.csdn.net/ccccdddxxx/article/details/8002983

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.