查找2進制中有多少個1
問題描述:請實現一個函數,輸入一個整數,輸出該數二進制表示中1的個數。例如把9表示成二進制是1001,有2位是1.因此如果輸入9,該函數輸出2.
看到這個題,我們首先可以想到的是位運算,只要考慮最右邊哪一位是不是1,如果是就加一,如果不是就右移,相當的簡單。那我們如何判斷最後一位是不是1,這時候我們可以用到&這個運算符。當最右邊一位是1時,&1=1;否則&1=0;如下代碼:
int number01(int n)
{
int number=0;
while(n)
{
if(n&1)
number++;
n>>1;
}
return number;
}
我們可以發現將數字右移和除以2的效果是一樣的,但是位運算會比除法運算效率高,所以我們應多用位運算。
☆當我們遇到的是一個負數,例如0x80000000,我們將這個負數右移一位的時候變成了0xC0000000,這是因爲這是一個負數,爲了保證她一直是一個負數,則最高位必須是1,因此我們一直右移,最後會變成0xFFFFFFFF而陷入死循環當中。
因此我們就想着把1左移,來計算個數,如下代碼:
int number02(int n)
{
int number=0;
int m=1;
while(n)
{
if(n&m)
number++;
m=m<<1;
}
return number;
}
有一種神奇的辦法。只要一個數字不爲0,則他至少有一個1.這時候我們讓他與上這個數字減一。例如:10010-1=01101 即相當於對這個數的最右邊的那個數一直到從右往左的第一個1,這塊的所有數作了取反操作。這時候與操作, 10010&10001=10000;這樣這個數字就少了一個1;10000-1=01111,01111&10000=0;如上思路就是每進行一次循環就少一個1.代碼如下:
int number03(int n)
{
int number = 0;
while(n)
{
number++;
n=n&(n-1);
}
return number;
}