[編程題]統計二進制中1的個數

問題:
輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

解題思路:
因爲負數用補碼錶示,對於負數右移時,在最高位補得是1,因此負數移位位產生無限個1,陷入死循環。

出現死循環的錯誤答案:

int NumberOf1_CanNotUse(int n) {
    int count = 0;
    while (n != 0) {
// 用1和n進行位與運算,結果要是爲1則n的2進制形式最右邊那位肯定是1,否則爲0
       if ((n & 1) == 1) {
           count++;
       }
       //把n的2進制形式往右推一位
       n = n >> 1; //負數右移,首位補一,導致無數個1
    }
    return count;
}

答案1:解決負數死循環問題
思想:當n爲負數的時候,可以將最高位的符號位1變成0,就是n & 0x7FFFFFFF,這樣就把負數轉化成正數了,唯一差別就是最高位由1變成0,因爲少了一個1,所以count加1。之後再按照while循環裏處理正數的方法來操作就可以啦!

int NumberOf1(int n) {
    int count = 0;
    if(n < 0){
        n = n & 0x7FFFFFFF;
        ++count;
    }
    while(n != 0){
        count += n & 1;
        n = n >> 1;
    }
    return count;
}

答案2:用1左移
思想:用1(1自身左移運算,其實後來就不是1了)和n的每位進行位與,來判斷1的個數

int NumberOf1_low(int n) {
    int count = 0;
    int flag = 1;
    while (flag != 0) { // 直到1左移超出int範圍變爲0,要循環32次。
        if ((n & flag) != 0) {
            count++;
        }
        flag = flag << 1;
    }
    return count;
}

答案3:最優解:用(n - 1) & n

int NumberOf1(int n) {
    int count = 0;
    while (n != 0) {
        ++count;
        n = (n - 1) & n;
    }
    return count;
}

引用:
1、題目來源於牛客網:二進制中1的個數
2、答案與解題思路來源於:AlenZhang與writezen

總結:

1、善於利用以爲運算符和按位與&。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章