求一個unsigned int 數的二進制表示中有多少個1?這是一道面試題可以用以下的一些方案。第一種是很容易想到的采用循環的方式并且與1進行位與運算,具體代碼如下。
假如你是第一次看到這些代碼,你是否能看明白?呵呵,本人第一次看到這些代碼的時候看了好久才感覺好像有點明白。下面我就以一個例子來說明上面的代碼是如何做到的。假如參數是0xffffffff。第一行代碼:nValue = ((0xaaaaaaaa & nValue)>>1) + (0x55555555 & nValue);a的二進制表示是:10105的二進制表示是:01010xffffffff 與 0xaaaaaaaa 進行與運算之后是0x10101010101010101010101010101010然后再進行左移操作后是0x010101010101010101010101010101010x55555555 & nValue 進行與運算之后是0x01010101010101010101010101010101然后0x01010101010101010101010101010101 & 0x01010101010101010101010101010101得到0x10101010101010101010101010101010我們把得到的結果分成16組0x10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10每組的10單獨來看是不是十進制的2我們0x01010101010101010101010101010101和0x01010101010101010101010101010101這兩個數也按照上面的方法分成16個組0x01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 0x01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01那么這兩個數的每一個組都是01 那么兩個01 里面有幾個1,是不是2個。這是2是不是二進制的10,然后16個10組合起來是不是0x10101010101010101010101010101010
第二行代碼:nValue = ((0xcccccccc & nValue)>>2) + (0x33333333 & nValue);此時nValue是0x10101010101010101010101010101010c的二進制表示是:11003的二進制表示是:00110xcccccccc 與 nValue) 進行與運算之后是0x10001000100010001000100010001000然后再進行左移操作后是0x001000100010001000100010001000100x33333333 & nValue 進行與運算之后是0x00100010001000100010001000100010
然后0x00100010001000100010001000100010 & 0x00100010001000100010001000100010得到0x01000100010001000100010001000100我們把得到的結果分成8組0x0100 0100 0100 0100 0100 0100 0100 0100每組的0100單獨來看是不是十進制的4 總共有多少個4?是不是8個,8×4=32。
以下的代碼: nValue = ((0xf0f0f0f0 & nValue)>>4) + (0x0f0f0f0f & nValue); nValue = ((0xff00ff00 & nValue)>>8) + (0x00ff00ff & nValue); nValue = ((0xffff0000 & nValue)>>16) + (0x0000ffff & nValue);請自己按照上面的方法做一遍,就會發現規律:第一次32位數分成32組,第二次分成16組,第三次分成8,第四次分成4,第五次分成2組。如果還是不明白請多看看,然后多選擇幾個參數進行試驗,多試幾次肯定會明白的。
看了這么多解法是不是有中很過癮的感覺,當我知道有這么多解法是也很過癮,也很遺憾。遺憾什么呢?遺憾當時我碰到這道面試題的時候只想到了采用循環的方法,可是那個面試題上明確說明不準使用循環!!當時很郁悶!!鄭重聲明:上面最后兩個解法非本人原創,本人只是總結歸納,向想出這么好方法的前輩高人致敬!