問題:
對乙個4位元組的無符號整形變數,求其二進位制表示中「1」的個數,要求演算法的執行效率盡可能高。
解法一(位遍曆法):使用位操作,移位後來判斷是否有1存在,利用v&0x01和v>>=1。
解法二(1遍曆法):在每次判斷中只與1的個數進行判斷,利用v&=v-1。
解法三(二分累加法):依次連續兩位相加,連續四位相加,連續八位相加。以上操作得到4個八位數,每個八位數的值表示8個數字之和(也就是這8位中1的個數),然後將每個八位數與緊接著前面的八位數相加,仍然得到4個八位數,但每個八位數的值表示16個數字之和(也就是這16位中1的個數),最後將每個八位數與前面再前面的乙個八位數相加,最後取第乙個八位數中前6位的值(這個值最多能表示63,大於1的最多個數32)。
參考1: int count(unsigned x)
將第2行的x看成16個連續的2個二進位制數字ab,a和b分別表示1個二進位制數,0x55555555在每連續的2個二進位制數字上都是01,則ab-(ab>>1)&01=ab-a=2*a+b-a=a+b表示x的連續2個二進位制數字之和。
將第3行的x看成8個連續的4個二進位制數字ab,a和b分別表示2個二進位制數,且值分別是x的對應2個二進位制數字之和,0x33333333在每連續的4個二進位制數字上都是0011,則ab&0011
+(ab>>2)&0011=b+a=a+b表示x的連續4個二進位制數字之和。
將第4行的x看成4個連續的8個二進位制數字ab,a和b分別表示4個二進位制數,且值分別是x的對應4個二進位制數字之和,0x0f0f0f0f在每連續的8個二進位制數字上都是00001111,則ab
&00001111
+(ab>>2)&00001111=b+a=a+b表示x的連續8個二進位制數字之和。
將第5行的x看成4個連續的8個二進位制數字abcd,a,b,c和d分別表示8個二進位制數,且值分別是x的對應8個二進位制數字之和,x+(x>>8)=abcd+abc=a(a+b)(b+c)(c+d)。繼續第6行,x+(x>>16)=a(a+b)(b+c)(c+d)+a(a+b)
=a(a+b)(a+b+c)(a+b+c+d)
。最後8個二進位制數(a+b+c+d)就是x的32個二進位制數字之和。
解法四(累加取餘法):首先將連續三位相加,再將連續的6位相加,得到5個數(每個數是連續的6個二進位制數字之和)+1個數(剩餘的2個二進位制數字之和),最後取餘得到32個二進位制數字之和。
參考1: int bitcount(unsigned int u)
將第2行的u看成11個連續的3個二進位制數字abc,a,b和c分別表示1個二進位制數,033333333333在每連續的3個二進位制數字上都是011,&上它會去掉這3個二進位制數字上的最高位,011111111111在每連續的3個二進位制數字上都是001,&上它只保留這3個二進位制數字上的最低位,在這裡主要是保證前面的數字在右移後不會對該3個二進位制數字的加減產生影響,則ucount在連續的3個二進位製上的運算是abc-ab-a=4a+2b+c-2a-b-a=a+b+c,表示u的該3個二進位制數字之和。
將第3行的ucount看成6個連續的6個二進位制數字ab,a和b分別表示3個二進位制數,且值分別是u的對應3個二進位制數字之和,030707070707在每連續的6個二進位制數字上都是000111,則ab & 000111+(ab>> 3) & 000111
= b+a。在對結果取餘之前,該結果可看成6個連續的6個二進位制數字abcdef,a,b,c,d,e和f分別表示連續的6個二進位制數,且其值是u的對應該6個二進位制數字之和,該結果=f+64e+64^2d+64^3c+64^4b+64^5a,取餘63後(乘法對取餘運算有分配律(64*64*d)%63=((64%63)*(64%63)*(d%63))%63=d%63),得a+b+c+d+f,即u的32個二進位制數字之和,且a+b+c+d+f<=32<63,取餘操作對最後結果無影響,但如果是64位的資料就會有影響。
程式設計之美2 1 求二進位制中1的個數
最近一段的時間,一直在看程式設計之美之類的演算法書籍,剛開始看程式設計之美,感覺到難度太大,有時候也不願意去翻動這本書,不過,經過一段時間的修煉,我也徹底的喜歡上這本書了,書中的演算法涉及到很多方面,樹,鍊錶,位運算,陣列,hash表應用等等。由於最近事情也忙得差不多了,我重新寫了一遍程式設計之美中...
求二進位制中1的個數(程式設計之美2 1)
行文脈絡 解法一 除法 解法二 移位 解法三 高效移位 解法四 查表 擴充套件問題 異或後轉化為該問題 對於乙個位元組 8bit 的變數,求其二進位制 1 的個數。例如6 二進位制0000 0110 1 的個數為2,要求演算法效率盡量高。解法一 對於二進位制數來說,除乙個2,就少一位,可以判斷這個少...
程式設計之美2 1 二進位制中1的個數
int numberof 1 int n return count int is 2n int n 1 求這兩個數的異或 兩個數不同的位置都為1,這些位置都需要改變 2 統計異或結果中1的個數 int stepchangeto int m,int n int add int num1,int num...