1. 程式人生 > >位運算--統計一個數的二進位制序列中1的個數

位運算--統計一個數的二進位制序列中1的個數

        給出一個十進位制數,求出該數的二進位制序列中1的個數。比如 15 的二進位制序列是

00000000  00000000  00000000 00001111   1的個數是4.

下邊將給出幾種不同的解決辦法:

方法一:

int count_one(int num)
{
	int count = 0;
	while (num)
	{
		if (num % 2 == 1)
		{
			count++;
		}
		num = num / 2;
	}
	return count;
}


由於這種方法用到了模除運算,所以這個方法只能處理正數,對於負數,是不可以的。

方法二:

int count_one(int num)
{
	int count = 0;
	int i = 0;
	for (i = 0;i < 32;i++)
	{
		if ((num >> i) & 1 == 1)
		{
			count++;
		}
	}
	return count;
}


這種方法既可以計算正數,又可以計算負數,就是效率稍微低一點。比如有的十進位制數

轉換成二進位制後的位數遠遠小於32,然而我們又要移位判斷32回。

方法三:

</pre><pre name="code" class="cpp">int count_one(int num)
{
	int count = 0;
	while (num)
	{
		count++;
		num = num & (num-1);
	}
	return count;
}



這種解決辦法運用了一個數和比它小一的數進行邏輯與 ,二進位制中會少一個1.

舉例:7   0111

0110       邏輯與之後結果是: 0110

一個數如果是2的n次方,則 pow(2,n)&(pow(2,n)-1) == 0;利用這個可以判斷一個數是不

是2的n次方。

方法四:

先看圖:


int count_ones(int num)
{
	int m_2 = 0x55555555;
	int m_4 = 0x33333333;
	int m_8 = 0x0f0f0f0f;
	int m_16 = 0x00ff00ff;
	int b = (m_2&num) + ((num >> 1)&m_2);
	int c = (m_4&b) + ((b >> 2)&m_4);
	int d = (m_8&c) + ((c >> 4)&m_8);
	int g = (m_16&d) + ((d >> 8)&m_16);
	return g;
}


最後這個辦法,是按照4位元組int處理的,要是你看不懂,私信我吧。郵箱:

[email protected]