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

bigface1234fdfg發表於2015-01-22

求二進位制數中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


《程式設計之美》




相關文章