求二進位制中1的個數(程式設計之美2 1)

2021-09-22 10:48:25 字數 2120 閱讀 8938

行文脈絡

解法一——除法

解法二——移位

解法三——高效移位

解法四——查表

擴充套件問題——異或後轉化為該問題

對於乙個位元組(8bit)的變數,求其二進位制「1」的個數。例如6(二進位制0000 0110)「1」的個數為2,要求演算法效率盡量高。

解法一

對於二進位制數來說,除乙個2,就少一位,可以判斷這個少的位來確定「1」的個數。

例如:6(0000 0110)

0000 0110 / 2 = 0000 0011     ----少的一位為0

0000 0011 / 2 = 0000 0001     ----少的一位為1

0000 0001 / 2 = 0000 0000     ----少的一位為1

運算元數已經為0,到此結束

參考**

int count_1(int

val)

return

num;

}

效能:時間複雜度o(log2v),即二進位制數的位數;空間複雜度o(1)

解法二

對於二進位制數來說,除法是用移位完成。

例如:6(0000 0110)

0000 0110 >> 1 = 0000 0011     ----少的一位為0

0000 0011 >> 1 = 0000 0001     ----少的一位為1

0000 0001 >> 1 = 0000 0000     ----少的一位為1

運算元數已經為0,到此結束

參考**

int count_2(int

val)

return

num;

}

效能:時間複雜度o(log2v),即二進位制數的位數;空間複雜度o(1)

解法三

對於上述演算法,有個問題,比如1000 0000,大把的時間用在沒用的0上,最好尋求一種直接判斷「1的個數。

通過觀察可以找到規律:對於數a, a = a & (a-1)就可以去除a的最後乙個1

例如:6(0000 0110)

0000 0110 & 0000 0101 = 0000 0100     

0000 0100 & 0000 0011 = 0000 0000

運算元數已經為0,到此結束

參考**

int count_3(int val)

return

num;

}

效能:時間複雜度o(m),即二進位制中「1」的個數,空間複雜度o(1)

解法四

查表法,把0~255這256個數的結果全部儲存在陣列中,val直接作為下標,counttable[val]即為結果。典型的用空間換時間。

參考**

int count_5(int

val)

;

return

counttable[val];

}

效能:時間複雜度:o(1), 空間複雜度o(n)

整個程式執行參考

結果

擴充套件問題

1. 給定兩個正整數(二進位制表示)a、b,如何快速找出a和b二進位制表示中不同位數的個數。

思路

首先a和b進行異或操作,然後求得到的結果中1的個數(此問題)。

2. 判斷乙個數是否是2的冪

bool powerof2(int

n)

程式設計之美 求二進位制中1的個數

1.問題描述 實現乙個函式,輸入乙個無符號整數,輸出該數二進位制中的1的個數。例如把9表示成二進位制是1001,有2位是1,因此如果輸入9,該函式輸出2 2.分析與解法解法1 利用十進位制和二進位制相互轉化的規則,依次除餘操作的結果是否為1 如下 int count1 unsigned int v ...

求二進位制數中1的個數 《程式設計之美》

求二進位制中1的個數。對於乙個位元組 8bit 的變數,求其二進位制表示中 1 的個數,要求演算法的執行效率盡可能的高。先來看看樣章上給出的幾個演算法 解法一 每次除二,看是否為奇數,是的話就累計加一,最後這個結果就是二進位制表示中1的個數。解法二 同樣用到乙個迴圈,只是裡面的操作用位移操作簡化了。...

程式設計之美 求二進位制數中1的個數

題目 對於乙個位元組的無符號整型變數,求其二進位制表示中 1 的個數,要求演算法的執行效率盡可能高。題目很簡單,一般人都可以用最直接的方法求解出來,通過求餘和模除運算。對二進位制操作過程中,除以乙個2,原來的數就會少乙個0,如果除過程中余1,則表示當前位置有乙個1,計數值加1,很簡單。但從執行效率來...