行文脈絡
解法一——除法
解法二——移位
解法三——高效移位
解法四——查表
擴充套件問題——異或後轉化為該問題
對於乙個位元組(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效能:時間複雜度o(log2v),即二進位制數的位數;空間複雜度o(1)val)
return
num;
}
解法二
對於二進位制數來說,除法是用移位完成。
例如: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效能:時間複雜度o(log2v),即二進位制數的位數;空間複雜度o(1)val)
return
num;
}
解法三
對於上述演算法,有個問題,比如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)效能:時間複雜度o(m),即二進位制中「1」的個數,空間複雜度o(1)return
num;
}
解法四
查表法,把0~255這256個數的結果全部儲存在陣列中,val直接作為下標,counttable[val]即為結果。典型的用空間換時間。
參考**
int count_5(int效能:時間複雜度:o(1), 空間複雜度o(n)val)
;
return
counttable[val];
}
整個程式執行參考
結果
擴充套件問題
1. 給定兩個正整數(二進位制表示)a、b,如何快速找出a和b二進位制表示中不同位數的個數。
思路
首先a和b進行異或操作,然後求得到的結果中1的個數(此問題)。
2. 判斷乙個數是否是2的冪
bool powerof2(intn)
程式設計之美 求二進位制中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,很簡單。但從執行效率來...