統計整數二進制表示中1的個數

解決這個問題第一想法確定是一位一位的去判斷,是1計數器+1,不然不操做,跳到下一位,十分容易,編程初學者就能夠作獲得!算法

 

因而很容易獲得這樣的程序:編程

 

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


 

 


或者用牛逼的位運算:循環

 

int Sum1ByBin(int num)
{
	int sum = 0;
	while (num)
	{
		sum += num&1;
		num>>1;
	}
	return sum;
}

 

 

上面這兩篇代碼是用的一樣的算法, 時間複雜度是二進制的位數,因而能夠想一下,有沒有隻有與二進制中1的位數相關的算法呢?二進制

能夠考慮每次找到從最低位開始遇到的第一個1,計數器加1而後把它清零,而後繼續找下一個1。方法就是n&(n-1),這個操做對比當前位高的位沒有任何影響,程序

對低位徹底清零。舉個栗子吧!5。 5是101,第一次運算101&100 == 100,而且計數器加一,第二次運算100&011 == 0,計數器加一。循環結束啦!方法

因此5有2個1。牛逼吧! 看看代碼是怎麼實現的:時間

 

int Sum1byBin(int num)
{
	int sum = 0;
	while(num)
	{
		num &= num-1;
		sum++;
	}
	return 0;
}

非常簡單,這就是位運算的好處,聽說這個算法沒把位運算髮揮到極致,也沒有獲得這個算法最優解。while

 

請讀者先look一段代碼,看看能不能看懂是什麼功能:初學者

 

int Sum1byBin(int num)
{
	num =	(num&0x55555555)	+	((num>>1)&0x55555555);
	num = (num&0x33333333)	+	((num>>2)&0x33333333);
	num	=	(num&0x0f0f0f0f)	+	((num>>4)&&0x0f0f0f0f);
	num	=	(num&0x00ff00ff)	+	((num>>4)&&0x00ff00ff);
	num	=	(num&0x0000ffff)	+	((num>>4)&&0x0000ffff);

	return num;
}

臥槽,這個是在玩什麼中的製表符致使空格這麼大的不怪我!位運算

 

回想第一次遇到這個代碼的時候我第一印象,這是什麼**玩意,後來通過分析而且有高手幫助理解,這個功能正是利用了位運算,將一個數中二進制表中1 的個數算了出來。利用的是分治思想,先計算每對相鄰的2位中有幾個1,再計算相鄰的4位有一個1 ,再計算相鄰的8位、16位、32位有幾個1,到此結束,32位的機器int就是32位,因此算

到32位就夠啦!!!

相關文章
相關標籤/搜索