編程之美【01】


  《編程之美》之前有看過,不過看完之后不僅啥也沒記住,反而是把自己繞得一團暈,重讀《編程之美》也是想重新梳理一下算法中的邏輯,並試圖找出那些所謂“美”的算法的共性,同時也希望能夠結交一些有着共同愛好的童鞋。好了,廢話到此,咱們開始吧。

  1、題目:對於一個字節(8bit)的變量,求其二進制表示中 “1” 的個數,要求算法的執行效率盡可能高。 

  解法一、

  思路:(輸入)變量為125,其二進制表示為01111101,統計該二進制表示中“1”出現的個數,可(從低位到高位)依次統計每位上“1”出現情況。

  計算:

  1、計算(輸入)變量二進制表示中最低位數字(num % 2),若為“1”則count加1;

  2、計算(輸入)變量二進制表示向右位移一位值(num / 2);

  3、迭代步驟1、步驟2,直到(輸入)變量值為0;

  4、返回count值。

  代碼:

    public int countNumberOne(int inputNumber) {
        int retCount = 0;
        
        while(inputNumber != 0) {
            if(1 == (inputNumber % 2)) {
                ++retCount;
            }
            inputNumber /= 2;
        }
        
        return retCount;
    }

  注:該算法時間復雜度為O(N),N為輸入變量的二進制表示長度。

  解法二、

  思路:解法二是對解法一的改進,對於(輸入)變量只需統計“1”的出現次數即可。我們知道num & num – 1的二進制運算,是對num最低“1”位計算為“0”,特別地,若num & num – 1 = 0,則表示num為2的冪次方。因此,可直接依次(從低位到高位)統計最低“1”位個數。

  計算:

  1、計算(輸入)變量二進制表示是否為0,若不為0,則count加1;

  2、計算(輸入)變量二進制表示最低“1”位值變為“0”(num &= num –1);

  3、迭代步驟1、步驟2,直到(輸入)變量值為0;

  4、返回count值。

  代碼:

    public int countNumberOne2(int inputNumber) {
        int retCount = 0;
        
        while(inputNumber != 0) {
            retCount++;
            inputNumber &= (inputNumber - 1);           
        }
        
        return retCount;
    }

  注:該算法時間復雜度為O(M),M為輸入變量的二進制表示中“1”的個數。

  解法三、

  思路:因為題目要求輸入變量長度為8bit,即一個字節,其取值范圍為0~255。因此,可直接建立0~255中每個數字所對應“1”出現個數的關系映射表,鍵值(key–value)關系可簡單通過數組來表示:數組下標(i)表示關鍵字(key),即所要查找的數字;數組值(arr[i])表示所要查找的結果,即“1”出現個數。

  計算:

  1、裝載關系映射表(即0~255中每個數字所對應“1”個數的映射關系);

  2、以輸入數字為鍵值(key),查找關系映射表中該鍵值對應的value值,並返回。

  代碼:

    static int[] countTable = null;
    static void loadCountTable() {
        countTable = new int[256];
        for(int i = 0; i < 256; i++) {
            countTable[i] = countNumberOne(i);
        }
}

    public int countNumberOne3(int inputNumber) { 
        if(countTable == null) {
            loadCountTable();
        }
        
        return countTable[inputNumber];
    }

  注:該算法時間復雜度為O(1),空間復雜度為O(2 ^ n),n為輸入變量最大長度。

  另:該算法為典型的空間換時間案例,得益於存儲開銷遠低於計算(cpu)開銷,空間換時間在計算機領域中十分常見,如:搜索引擎中的倒排索引、網站中的降級處理(如某電子商務公司在價格戰中會將部分動態頁面靜態化,以提高響應時間)等。如果大家有什么這方面的案例,希望能共同探討,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM