數據結構與算法-位運算

位運算
位運算是把數字用二進制表示以後,對每一位上的0或者1的運算。理解位運算的第一步是理解二進制。二進制是指數字每一位都是0或者1,如十進制的2轉換爲二進制以後是10,而十進制的10轉換爲二進制以後是1010。在程序員圈子裏有一個流傳了好久的笑話,說世界上有10種人,一種人知道二進制,另外一種人不知道二進制。 下面是幾個常見的關於位運算的算法題:
基本位運算
位運算總共只有5種運算:與&,或|,異或^,左移<<,右移>>.
與,或,異或的運算規則:程序員


左移,右移運算規則:
左移運算m < < n表示把m左移n位,左移n位時,最左邊的n位被丟棄,同時在最右邊補上n個0.如:面試

00001010 << 2 = 00101000
10001010 << 3 = 01010000


右移運算m > > n 表示把m右移n位,右移n位時,最右邊的n位被丟棄,最左邊根據該數字的類型決定,若是該數是一個無符號數值,則用0填補最左邊的n位。若是該數是一個有符號數值,用數字的符號位填補最左邊的n位,也就是若是該數是正數,則用0填補最左邊的n位。若是該數是負數,則用1填補最左邊的n位(補充知識點:一個有符號的數字,它的二進制最高位若是是1,則代表該數字爲負數,若是是0則爲正數)。如對有符號8位數字進行右移:算法

00001010 >> 2 = 00000010
10001010 >> 3 = 11110001


整數的二進制中1的個數
題目:實現一個函數,輸入一個整數,輸出該數二進制表示中1的個數。如輸入9,9的二進制表示是1001,有兩個1,所以輸入9該函數返回2.數組

public int count (int n) {
    int res = 0;
    while (n!=0) {
        n = n&(n-1);//該語句的做用是將二進制數中最右邊的1變爲0
        res++;
    }
    return res;
}

不用額外變量交換兩個整數的值
只須要以下三行代碼:數據結構

a = a^b;
b = a^b;
a = a^b;

 

如何判斷一個整數是否是2的整數次方
若是一個整數是2的整數次方,則它的二進制表示中應該只有一位是1,其它位都爲0,如 2 的二進制表示爲0010,4的二進制表示爲0100。因此把這個整數減去1,再與自身做&運算(如求整數中1的個數的方法),這樣該整數中惟一的一個1就變爲0。函數

public boolean isIntPower(int n) {
    return (n&(n-1)) == 0;
}


兩個整數m和n,計算須要改變m二進制表示中多少位,才能夠獲得n.
如4的二進制表示爲0100,2的二進制表示爲0010,4須要改變2位才能夠變成2.分兩步求解:第一步求兩個整數的異或,第二步統計異或結果中1的個數。學習

public int count (int m,int n) {
    int a = m^n;
    int res = 0;
    while (a!=0) {
        a = a&(a-1);//該語句的做用是將二進制數中最右邊的1變爲0
        res++;
    }
    return res;
}


在其餘數都出現偶數次的數組中找出出現奇數次的數
給定一個數組arr,其中只有一個數出現了奇數次,其餘數都出現了偶數次,打印這個數。spa

public void getOddTimesNumber(int[] arr) {
    int eO = 0;
    for (int cur : arr) {
        eO = eO ^ cur; 
    }
    System.out.println(eO+"");
}


學習算法的記錄和整理,若有錯誤或意見請幫忙指出,之後會持續更新。。。。code


參考書籍:
《程序員代碼面試指南:IT名企算法與數據結構題目最優解》—左程雲
《劍指Offer》 —何海濤blog

相關文章
相關標籤/搜索