解法一:除2看餘數
int count(byte v)
v = v/ 2;
} return num;
}
解法二:使用位操作
int count(byte v)
return num;
}
解法三:不斷清除n的二進位制表示中最右邊的1
為什麼n &= (n – 1)能清除最右邊的1呢?因為從二進位制的角度講,n相當於在n - 1的最低位加上1。舉個例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右邊的1(其實就是最高位的1,因為8的二進位制中只有乙個1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二進位制表示中最右邊的1(也就是最低位的1)。
int count(byte v)
return num;
}
解法四:
int bitcount5(unsigned int n)
第一行**的作用
先說明一點,以0開頭的是8進製數,以0x開頭的是十六進製制數,上面**中使用了三個8進製數。
將n的二進位制表示寫出來,然後每3bit分成一組,求出每一組中1的個數,再表示成二進位制的形式。比如n = 50,其二進位制表示為110010,分組後是110和010,這兩組中1的個數本別是2和3。2對應010,3對應011,所以第一行**結束後,tmp = 010011,具體是怎麼實現的呢?由於每組3bit,所以這3bit對應的十進位制數都能表示為2^2 * a + 2^1 * b + c的形式,也就是4a + 2b + c的形式,這裡a,b,c的值為0或1,如果為0表示對應的二進位制位上是0,如果為1表示對應的二進位制位上是1,所以a + b + c的值也就是4a + 2b + c的二進位制數中1的個數了。舉個例子,十進位制數6(0110)= 4 * 1 + 2 * 1 + 0,這裡a = 1, b = 1, c = 0, a + b + c = 2,所以6的二進位制表示中有兩個1。現在的問題是,如何得到a + b + c呢?注意位運算中,右移一位相當於除2,就利用這個性質!
4a + 2b + c 右移一位等於2a + b
4a + 2b + c 右移量位等於a
然後做減法
4a + 2b + c –(2a + b) – a = a + b + c,這就是第一行**所作的事,明白了吧。
第二行**的作用
在第一行的基礎上,將tmp中相鄰的兩組中1的個數累加,由於累加到過程中有些組被重複加了一次,所以要捨棄這些多加的部分,這就是&030707070707的作用,又由於最終結果可能大於63,所以要取模。
需要注意的是,經過第一行**後,從右側起,每相鄰的3bit只有四種可能,即000, 001, 010, 011,為啥呢?因為每3bit中1的個數最多為3。所以下面的加法中不存在進製的問題,因為3 + 3 = 6,不足8,不會產生進製。
tmp + (tmp >> 3)-這句就是是相鄰組相加,注意會產生重複相加的部分,比如tmp = 659 = 001 010 010 011時,tmp >> 3 = 000 001 010 010,相加得
0010100
10011
000001
010010
001011100
101
001 + 101 = 1 + 5 = 6,所以659的二進位制表示中有6個1
注意我們想要的只是第二組和最後一組(綠色部分),而第一組和第三組(紅色部分)屬於重複相加的部分,要消除掉,這就是&030707070707所完成的任務(每隔三位刪除三位),最後為什麼還要%63呢?因為上面相當於每次計算相連的6bit中1的個數,最多是111111 = 77(八進位制)= 63(十進位制),所以最後要對63取模。
求二進位制數中1的個數
解法一 可以舉乙個八位的二進位制例子來進行分析。對於二進位制操作,我們知道,除以乙個2,原來的數字將會減少乙個0。如果除的過程中有餘,那麼就表示當前位置有乙個1。以10 100 010為例 第一次除以2時,商為1 010 001,余為0。第二次除以2時,商為101 000,余為1。因此,可以考慮利用...
求二進位制數中1的個數
對於乙個位元組 8bit 的變數,求其二進位制表示中 1 的個數,要求演算法的執行效率盡可能地高。解法一 可以舉乙個八位的二進位制例子來進行分析。對於二進位制操作,我們知道,除以乙個2,原來的數字將會減少乙個0。如果除的過程中有餘,那麼就表示當前位置有乙個1。int count int v int ...
求二進位制數中1的個數
對於乙個位元組 8bit 的無符號整型變數,求其二進位制表示中 1 的個數。c codes as below using system class program static void main string args program program new program for int i 0...