這是乙個經常會在筆試和面試中遇到的題目,今天我做到了這個題目,就來分享一下我對這個題目的解決思路。
首先拿到這個題目,我們的基本思路是:先判斷最後一位是否為1,接著把數字依次右移,判斷每一位是否為1,直到整數變為0為止。基於這個思路我們可以寫下如下的**:
//int count(int n)
//// n = n>>1;
// }
// return num;
//}
在上面的**中,其實除以2和右移一位的結果是一樣的,那麼我們是否可以用除以2代替右移呢???答案是,不可以。
因為除法運算比移位運算效率低得多,在實際程式設計中,我們應該盡量用移位運算代替乘除法。
但是呢,以上的**是容易引起死迴圈的,比如說我們輸入乙個負數,比如0x80000000,執行時把負數右移一位,並不是簡單地把最高位的1移到第二位變成0x40000000,而是0xc0000000。因為移位前是個負數,仍然要保證移位後是個負數,因此移位後的最高位會設為1。如果一直做右移運算,最終這個數字會變成0xffffffff,而陷入死迴圈。
為了避免死迴圈,我們可以不右移數字,首先把數字n和1做與運算,判斷n的最低位是不是1。接著把1左移一位得到2,再和n做與運算,就能判斷n的次低位是不是1.這樣反覆左移,每次都能判斷n的其中一位是不是1.基於這種思路,**如下:
//int count(int n)
//// flag = flag << 1;
// }
// return count;
//}
這種解決方法看起來還不錯,不過還是有比它更高效的方法,那就是整數有多少個1就迴圈多少次。我們的實現方法是:把乙個整數減去1,再和原整數做與運算,會把該整數最右邊乙個1變為0,那麼乙個整數的二進位制表示中有多少個1就可以進行多少次這樣的操作。基於這種思路,我們可以寫下如下的**:
int count(int n)
return num;
}
整體測試**如下:
int main()
{ int n = 0;
cout<<"輸入數字:";
cin>>n;
int ret = count(n);
cout<<"1的個數是:"<
求二進位制中1的個數
在 程式設計之美 一書中有一節提到如何求乙個位元組的無符號整型變數二進位制表示中中1的個數,主要提到了四種方法。下面簡單介紹一下 1.求餘法 在將十進位制數轉換為二進位制數時,採用除2取餘法。將每次除2得到的餘數儲存起來逆序輸出便是該十進位制整數的二進位制表示。因此可以採用這種方法去統計1的個數。i...
求二進位制中1的個數
解法有很多種 以乙個位元組無符號位元組變數作為例子 解法一 求餘法 在將十進位制數轉換為二進位制數時,採用除2取餘法。將每次除2得到的餘數儲存起來逆序輸出便是該十進位制整數的二進位制表示。因此可以採用這種方法去統計1的個數。public int count byte n return sum 解法二...
求二進位制中1的個數
如何快速的求乙個數二進位制表示時1的個數呢。除了用n n 1 外,還可以用下面的這種方法。1.最開始把相鄰奇數字和偶數字相加 2.然後相鄰4位相加,相鄰8為相加,相鄰16為的相加。得到最後1的個數。這種做法的複雜度的是log 位數 include include include using name...