判斷32位無符號整數二進位制中1的個數

2021-06-29 15:17:01 字數 1754 閱讀 7076

1、比較簡單和容易理解的方法就是逐位比較法:

#include using

namespace std;

int findone(unsigned int n)

int main()

這種方法的缺點是比較費時,時間長度取決於n的位數,時間複雜度o(n)。假如上千上萬位的話,每一位都要執行一遍,所用時間就很長了。

2、最直接的優化方法,其實就是空間換時間的思想:可以預建立乙個表,存放了從0~2^32每個數中1的個數,用時去查一下表就知道了。但這樣顯然要耗費很多的空間(至少2^32/(256/32)=512mb,哈哈,正是一般記憶體大小)。於是需要再優化:存放0-255每個數中1的個數,然後分段查詢。如下面把32位數分為4段,每段乙個位元組,所以有乙個256大小供查詢的表: 

char tone[256]="

\0\1\1\2\1\2……

"; //

後面省略

int findone(unsigned int n)

3、上次在阿里雲筆試,碰到一題也是求乙個整數中1的個數。

intfunc(unsignedintn)

returncount;

}

比如n=10,二進位制為1010,count=2。  

4、下面這種方法據說更快,但是我覺得不容易想出來。發現很多題目都可以用位運算來快速解決,可惜本人十分討厭使用它,總覺得在繞來繞去的,偉大的位運算...

int count_ones(unsigned a)

該**的思路是這樣的:2位2位為一組,相加,看看有幾個1。再4位4位為一組,相加,看看有幾個1......

為了簡單說明,先看看8位的情形。相應地,函式裡面的語句變成。

x = (x & 0x55) + ((x >> 1) & 0x55);    (1)

x = (x & 0x33) + ((x >> 2) & 0x33);    (2)

x = (x & 0x0f) + ((x >> 4) & 0x0f);    (3)

return x;

假設x=abcdefgh. 0x55=01010101

x & 0x55 = 0b0d0f0h.   (x>>1) & 0x55 = 0a0c0e0g。相加。就可以知道2位2位一組1的個數。

比如x=11111111

x= (x & 0x55) + ((x >> 1) & 0x55); 之後x=10101010。你2位2位地看,10=2, 就是2 2 2 2, 就是說各組都是2個1。

比如x=00101001

x= (x & 0x55) + ((x >> 1) & 0x55); 之後x=00010101。你2位2位地看,就是0 1 1 1, 前1組只有0個1,後面的組都是1個1。

好啦。再來看。0x33=00110011。

x=abcdefgh. 

x=(x & 0x33)+((x >> 2)&0x33); 相當於, 00ab00ef + 00cd00gh。

因為語句(1)之後。ab指示了頭兩位有多少個1,cd指示了下兩位有多少個1。相加00ab+00cd就指示前4位有多少個1。這樣就是4位4位為一組。注意這樣的分組,組與組之間永遠都不會產生進製的。正因為不會產生進製,才可以分開來看。

下面的過程都是一樣的,不再多說。8位,16位,32位都一樣。

判斷32位整數二進位制中1的個數

收藏此頁 列印 it168知識庫 判斷32位整數二進位制中1的個數 iostream using namespace std intfindone unsigned intn intmain 2 優化 這樣的時間複雜度是t m m,取決於二進位制數的位數m。如果要求在更短時間內求出,應該如何做呢?如...

判斷二進位製半整數(二進位制)

10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借1000塊錢,然後tokitsukaze大佬說,借你1024吧,湊個整數。沒錯在2進製下1024是 二進位制整數 乙個正整數滿足其值為2的k次方 k為正整數 我...

判斷二進位製半整數

判斷二進位製半整數 時間限制 c c 1秒,其他語言2秒 空間限制 c c 262144k,其他語言524288k 64bit io format lld 10年後,tokitsukaze大佬已經變成了年收入超百萬的的精英程式設計師,家裡沒錢也沒礦的teitoku,找tokitsukaze大佬借10...