1. 程式人生 > >位運算的相關題型

位運算的相關題型

位運算是把數字用二進位制表示之後,堆每一位上0或者1的運算。

1.請實現一個函式,輸入一個整數,輸入該數的二進位制表示中1的個數;

解法一:

一個整數有32個二進位制位,只需要對這32位的每一位判斷是否為1來統計其中一個個數;

如何判斷每一位呢?看下面這個過程,用八位來模擬;

第一位:0000 1010  & 0000 0001  = 0000 0000  ;   結果為零,表示該二進位制位是0;

第二位:0000 1010  & 0000 0010 =  0000 0010;結果不為0,表示該二進位制位是1;

...

依次判斷至結束;

int NumberOf1(int num)
{
	unsigned int flag = 1;
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		if ((num & flag))
		{
			count++;
		}
		flag = flag << 1;
	}

	return count;
}
上面的方法不管是幾個1,1在高位還是低位都需要迴圈32次,下面這個解法就有效的減少了迴圈次數;

解法二:

說這個解法之前,先來個預備知識,一個數減去1,相當於最低位是1的這一位取反,以這位為分隔符,左邊不變,右邊的都變為1;比如:10 - 1 == 1010 - 1  等於1001;

9 - 1 == 1001 -1 等於 1000;由此可以總結:一個數減去1,都是把最右邊的1變為0,如果它右邊患有0的話,所有的0變為1;而它左邊的所有位保持不變;

我們把一整數和這個整數減去1的結果做與運算,10 & (10 - 1)== 1010 & 1001 等於 1000;相當與這個整數二進位制位中1的個數減少1個;

解法二的思路就是,把一個整數和這個整數減去1之後的結果相與,每次減少1個1,直到結果為零,與了多少次,就有多少個1;

int NumberOf1(int num)
{
	int count = 0;
	while (num)   //一個數&(這個數 - 1),相當於減少一個二進位制中的1;
	{
		count++;
		num = num & (num - 1);
	}

	return count;
}
2.用一條語句判斷一個整數是不是2的整數次方?

先來普及一條知識點:一個整數如果是2的整數次方,那麼它的二進位制表示中有且只有一位是1;

下來解出這個問題是不是 so easy,直接利用上一題解法二的思路判讀1的個數是不是1個就可以了;

bool Check2(int n)
{
	return (n & n - 1) ? false : true;
}