碼上快樂
1秒登錄
首頁
榜單
標簽
關於
搜索
相關內容
簡體
繁體
判斷32位整數二進制中1的個數的算法
本文轉載自
查看原文
2016-09-20 16:33
2675
C語言
再轉 http://blog.chinaunix.net/uid-20480343-id-1941577.html
今天在CU上看到了關於 “判斷32位整數二進制中1的個數的算法” 的問題。因為馬上就要下班,沒有時間再研究了。只好先把論壇中帖子的地址拷貝下來了。學習ing....
http://dev.bibts.com/32-1-t936968.htm
http://www.chinaunix.net/jh/23/795048.html
在下面的英文網址中,對這個問題有詳細的介紹:
http://www.everything2.com/index.pl?node=counting%201%20bits
http://www.everything2.com/index.pl?node=counting%201%20bits%20SPOILER
http://www.everything2.com/index.pl?node_id=1181258
剛開始看到這個問題的時候,我就傻乎乎的開始寫代碼:
unsigned int FindOneInNumber_00(unsigned int x)
{
unsigned int i,j=1;
unsigned int count=0;
for(i=0;i<32;i++)
{
if((x & j) != 0) count++;
j = j<<2;
}
return count;
}
下面是我寫的
很明顯我的這段代碼寫的是非常糟糕的。每次傳過來一個數字,我總是要進行32次掃描。就這一點就可以說我的代碼是典型的垃圾代碼,那么別人是不是有簡潔一點的代碼呢。在上面的三個英文網址中找到了一些東西。
unsigned int FindOneInNumber_01(unsigned int x)
{
unsigned int n;
for(n=0; x; x >>= 1)
if (x & 1) n++;
return n;
}
在英文文檔中,原作者給出的第一種方法。看到這樣的代碼,俺只能說自己太笨,代碼寫起來太傻。不就是查查一個數字中 1 的個數嗎?自己為啥非得要把所有的 位 都掃描呢? 這是一個值得想想的問題。 原作者給出的代碼已經是很不錯了,不過,在下面接着他又給出了第二種解法,這第二種解法,更是簡潔 優雅 。
unsigned int FindOneInNumber_02(unsigned int x)
{
unsigned int n;
for(n=0; x; n++)
x &= x-1;
return n;
}
原作者給出的第二種方法明顯的要優於第一種方法。兩者的程序中,循環體執行完后,n表示 1 個個數。x的值變為 0 。兩者都達到了目的,循環次數也是一樣的。但是二者的區別就在於 第二種方法不用 執行條件判斷跳轉。當數據量的比較大的時候,二者的差距還是蠻大的。
原文作者又給出第三種方法來解決這個問題:
unsigned FindOneInNumber_03(unsigned int x)
{
const unsigned MASK1 = 0x55555555;
const unsigned MASK2 = 0x33333333;
const unsigned MASK4 = 0x0f0f0f0f;
const unsigned MASK8 = 0x00ff00ff;
const unsigned MASK16 = 0x0000ffff;
x = (x&MASK1 ) + (x>>1 &MASK1 );
x = (x&MASK2 ) + (x>>2 &MASK2 );
x = (x&MASK4 ) + (x>>4 &MASK4 );
x = (x&MASK8 ) + (x>>8 &MASK8 );
x = (x&MASK16) + (x>>16&MASK16);
return x;
}
原文作者的一個朋友又給出一種方法,【查表法】,不過,這樣要浪費一定的主存。這種方法也是一個很不錯的方法,不過,在單片機下開發的時候,就是個問題的了。象我們公司在單片機上開發游戲,所有的能夠給 圖片、聲音、程序的所有ROM空間僅僅 8MB,采用這種方法就是很不明智的一種選擇了。
unsigned numbits_lookup_table[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
6, 7, 6, 7, 7, 8
};
unsigned FindOneInNumber_04(unsigned int x)
{
unsigned n;
n = numbits_lookup_table[x & 0xff];
n += numbits_lookup_table[x>>8 & 0xff];
n += numbits_lookup_table[x>>16 & 0xff];
n += numbits_lookup_table[x>>24 & 0xff];
return n;
}
【本程序在Dev C++ 4.9.9.2 下編譯通過】
×
免責聲明!
本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。
猜您在找
窺探算法之美妙——統計整數二進制中1的個數
輸入一個整數,輸出該數32位二進制表示中1的個數。其中負數用補碼表示。
二進制中1的個數(位運算)
統計一個整數的二進制中1的個數(暴力)
Java之一個整數的二進制中1的個數
劍指offer—算法之位運算(二進制中1的個數)
位運算-二進制中1的個數(三種解法)
整數的二進制、位運算、邏輯與或
java:判斷二進制數據中第n位是否為1
輸入一個int型正整數,輸出它的二進制形式中數字1的個數
粵ICP備18138465號
© 2018-2025 CODEPRJ.COM