求二進位制數中1的個數(程式設計之美)
求二進位制數中1的個數
題目描述:對於一個位元組1BYTE = 8 bits的無符號變數,求其二進位制表示中1的個數,要求演算法的執行效率儘可能高。
題目分析:可以吧這個問題轉化為判斷這個數的最後1位數是否等於1,然後逐漸往右移位,不斷判斷下去,直到該數為零。
按照這種分析,那麼就有兩部分需要做:
1)判斷最後一位是否為零;
2)如果右移位。
這樣就有三種思路。
思路一:1)可以通過除以2,看餘數是否等於0/1實現;2)可以通過除以2;
思路二:1)可以通過和0x01按位與,如果結果為1就表示最後一位為1,否則就是0;2)可以右移位實現除以2;
思路三:1)可以通過v & (v-1)來實現,充分利用了相鄰數最後一個二進位制位相異的特點;2)同思路2.
程式碼如下:
// 思路2
#include<iostream>
typedef unsigned char BYTE; //BYTE型別在C++中是沒有的,其實它就是無符號字元型,人們一般關注它的長度,而不是型別
using namespace std;
int count(BYTE v)
{
int num = 0;
while(v)
{
num += v&0x01; //按位與
v >>= 1; //右移位
}
return num;
}
int main()
{
BYTE x = 255; //BYTE型別只有8bits, 所以最大隻能是255, 0-255
cout<<count(x)<<endl; //輸入1的個數
return 0;
}
其中的註釋幫助理解BYTE型別。
// 思路3
#include<iostream>
typedef unsigned char BYTE;
using namespace std;
int count(BYTE v)
{
int num = 0;
while(v)
{
//num += v&0x01;
//v >>= 1;
v &= (v-1);
num++;
}
return num;
}
int main()
{
BYTE x = 255;
cout<<count(x)<<endl;
return 0;
}
可以看出 v &= (v-1); 這樣子做就可以省去了右移位的操作,這樣更加簡單。
時間複雜度方面:
思路2,時間複雜度和v的二進位制位數有關,而一個數的二進位制的位數為logv,故O(logv);
思路3,直接和v中1的個數有關,是O(M).
思路1的和思路2的一樣,不過做法比思路2要大,因為位操作比除法和餘法要效率來的高~
參考:
關於BYTE:
http://bbs.csdn.net/topics/310267652
http://www.cxybl.com/html/bcyy/c/201109073136.html
《程式設計之美》
相關文章
- 二進位制中1的個數
- 【劍指offer】二進位制中1的個數
- JZ-011-二進位制中 1 的個數
- 02_Python學習筆記之統計整數二進位制中1的個數Python筆記
- 【刷演算法】二進位制中1的個數演算法
- offer通過--10二進位制中統計1的個數-2
- 二進位制求5個1的格式。。。。
- 劍指 Offer 15. 二進位制中1的個數
- 【劍指offer中等部分4】二進位制中1的個數(java)Java
- 二進位制漏洞挖掘之整數溢位
- 根據數字二進位制下 1 的數目排序排序
- 負數的二進位制數問題
- 三種語言實現計算二進位制中1的個數(C++/Python/Java)C++PythonJava
- C++輸入十進位制數,輸出對應二進位制數、十六進位制數C++
- 1417 二進位制數的大小
- 輸出二進位制數
- 二進位制 (小白進軍程式設計師)程式設計師
- 力扣 根據數字二進位制下1的數目排序力扣排序
- 知多一點二進位制中的負數
- leetcode-1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- leetcode.1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- leetcode1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- 設計一個十進位制轉化為隨意進位制的程式
- 整數轉化成八進位制、十六進位制、二進位制,以及轉回
- 對於十進位制數 -1023,包含符號位在內,至少需要多少個二進位制位表示該數符號
- 一看就懂二進位制、八進位制、十六進位制數轉換十進位制
- 計算機中的二進位制計算機
- 力扣1356.根據數字二進位制下1的數目排序力扣排序
- Python中整數移位及二進位制串操作Python
- 進位制之間的轉換之“十六進位制 轉 十進位制 轉 二進位制 方案”
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- 教你如何進行數倉字串、二進位制、十六進位制互轉字串
- 【程式設計師面試金典】 寫出一個程式,接受一個十六進位制的數值字串,輸出該數值的十進位制字串。(多組同時輸入 )程式設計師面試字串
- 負數補碼(16進位制轉10進位制的負數)
- 二進位制中為什麼負數是正數取反再加一
- 如何把十進位制的數輸入用二進位制全加器,並以十進位制輸出
- 牛客網 二進位制數(進位制轉換、北郵機試)
- 遞迴函式實現十進位制正整數轉換為二進位制,八進位制,十六進位制遞迴函式
- mysql二進位制日誌的引數介紹MySql