1. 程式人生 > >求二進位制中1的個數

求二進位制中1的個數

        這是一個經常會在筆試和麵試中遇到的題目,今天我做到了這個題目,就來分享一下我對這個題目的解決思路。

     首先拿到這個題目,我們的基本思路是:先判斷最後一位是否為1,接著把數字依次右移,判斷每一位是否為1,直到整數變為0為止。基於這個思路我們可以寫下如下的程式碼:

//int Count(int n)
//{
//	int num = 0;
//	while(n)
//	{
//		if((n & 0x01) == 1)
//		{
//			num++;
//		}
//		n = n>>1;
//	}
//	return num;
//}
       在上面的程式碼中,其實除以2和右移一位的結果是一樣的,那麼我們是否可以用除以2代替右移呢???答案是,不可以。因為除法運算比移位運算效率低得多,在實際程式設計中,我們應該儘量用移位運算代替乘除法。

       但是呢,以上的程式碼是容易引起死迴圈的,比如說我們輸入一個負數,比如0x80000000,執行時把負數右移一位,並不是簡單地把最高位的1移到第二位變成0x40000000,而是0xC0000000。因為移位前是個負數,仍然要保證移位後是個負數,因此移位後的最高位會設為1。如果一直做右移運算,最終這個數字會變成0xFFFFFFFF,而陷入死迴圈。

        為了避免死迴圈,我們可以不右移數字,首先把數字n和1做與運算,判斷n的最低位是不是1。接著把1左移一位得到2,再和n做與運算,就能判斷n的次低位是不是1.這樣反覆左移,每次都能判斷n的其中一位是不是1.基於這種思路,程式碼如下:

//int Count(int n)
//{
//	int count = 0;
//  unsigned int flag = 1;
//	while(flag)
//	{
//		if(n & flag)
//		{
//			count++;
//		}
//		flag = flag << 1;
//	}
//	return count;
//}
        這種解決方法看起來還不錯,不過還是有比它更高效的方法,那就是整數有多少個1就迴圈多少次。我們的實現方法是:把一個整數減去1,再和原整數做與運算,會把該整數最右邊一個1變為0,那麼一個整數的二進位制表示中有多少個1就可以進行多少次這樣的操作。基於這種思路,我們可以寫下如下的程式碼:
int Count(int n)
{
	int num = 0;
	while(n)
	{
		n = n&(n-1);
		num++;
	}
	return num;
}
        整體測試程式碼如下:
int main()
{
	int n = 0;
	cout<<"輸入數字:";
	cin>>n;
	int ret = Count(n);
	cout<<"1的個數是:"<<ret<<endl;
	system("pause");
	return 0;
}
         以上就是解題思路和程式碼實現,我也是參考了其他資料,結合自己對於這個問題的理解,總結出了這篇部落格,有什麼不對的地方,歡迎大家跟我提出。謝謝大家!



相關推薦

二進位制1”的個數

題目描述:對於一個位元組(8位)的無符號整型變數,二進位制表示中“1”的個數,要求演算法的執行效率儘可能高。 方法一 思路:首先比較好的方法是想到對二進位制數進行 >>和&,

程式設計之美:二進位制1個數

1.問題描述 實現一個函式,輸入一個無符號整數,輸出該數二進位制中的1的個數。例如把9表示成二進位制是1001,有2位是1,因此如果輸入9,該函式輸出2 2.分析與解法 解法1:利用十進位制和二進位制相互轉化的規則,依次除餘操作的結果是否為1  程式碼如下: int Count1(unsigned

演算法---二進位制1個數

學習的地址:原文地址 問題描述   任意給定一個32位無符號整數n,求n的二進位制表示中1的個數,比如n = 5(0101)時,返回2,n = 15(1111)時,返回4。 1.普通法   我總是習慣叫普通法,因為我實在找不到一個合適的名字來描述它,其實就是最簡

C語言二進位制1個數

#include <stdio.h> int main() { int num=-1; int count=0;     while(num) {  num=num&(num-1);  coun

二進位制1個數

        這是一個經常會在筆試和麵試中遇到的題目,今天我做到了這個題目,就來分享一下我對這個題目的解決思路。      首先拿到這個題目,我們的基本思路是:先判斷最後一位是否為1,接著把數字依次右移,判斷每一位是否為1,直到整數變為0為止。基於這個思路我們可以寫下如下

數字之美之-------二進位制1個數

 最簡單的方法就是,直接異或A^B,得等到的結果中1的個數就表示整數A和B的二進位制表示中有多少位是不同的。 這是一類問題的變形,原題是:求二進位制中1的個數? #include <stdio.h> void main() { int num=0;

2.1二進位制1個數

#include <iostream> #include <windows.h>   //byte型別標頭檔案 using namespace std; int Count(int v) { int num = 0; while (v){ v &

刷題筆記9——輸入整數對應二進位制1個數

題目描述 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 程式碼 將1每次左移,和輸入數字進行&運算,結果不為0,則cnt++ class Solution { public: int NumberOf1(int n) {

二進位制1/0的個數

設x為二進位制數1111 1111 1111 1010,則求x中0的個數操作: int countofZero(int x) { int N = 0; while (x + 1) { N++; x |= (x + 1)

隨筆-整數二進位制1個數

題目: 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 思路:暴力方法是 >>> 32次; 當一個二進位制數-1的時候,它最低位的1變成0,如果還有0那全部變成0; 如果它與原值進行與運算,那麼原值最低為的1 以及後面的全部變成0; pu

一個整數的二進位制1個數

題目:輸入一個整數,求該整數的二進位制表達中有多少個1。例如輸入10,由於其二進位制表示為1010,有兩個1,因此輸出2。 分析:這是一道很基本的考查位運算的面試題。包括微軟在內的很多公司都曾採用過這道題。 一個很基本的想法是,我們先判斷整數的最右邊一位是不是1。接著

計算1個數--計算一個整數二進位制1個數。要求效率儘可能的高。且能正確正數和負數的二進位制1個數

錯誤方法: 數字右移,這裡會涉及到移位的規則。 移位規則: 左移運算子m<<表示把m左移n位。左移n位的時候,最左邊的n位將被丟棄,同時在右邊補上n個0; 右移比左移稍微複雜一些,如果數字是一個無符號值或正數,右移時最左邊補0; 如果數字是

位運算--一個 數二進位制1個數

1.五種位運算: (1)&(與)–有0則0;無0則1; (2)|(或)–有1則1,無1則0; (3)^(亦或)–相同為0,不同為1; (4)>>右移(最右邊的位被拋棄)

【C語言】個數二進位制 1個數

求一個數的二進位制的1的個數 1,通過模除的方法 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> int main() { int i = 0;

一個位元組(8bit)的無符號整形變數,其二進位制1個數

問題:求一個位元組中二進位制1的個數,並顯示執行時間,精確到毫秒。本文提供了三個演算法。程式碼如下 #include "stdafx.h" #include<iostream> #include<time.h> #include<stdli

[PHP]演算法-二進位制1個數的PHP實現

二進位制中1的個數: 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 思路: 1.右移位運算>> 和 與運算& 2.先移位個然後再與1 &運算為1的就是1 3.這裡如果是負數就會出現死迴圈,負數右移後高位會一直補1 4.因此要實現一下無符號位移 無符

返回引數二進位制 1個數

程式碼: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> int CountOneBits(unsigned int value) { //1.轉換為二進位制,即對2反向取模

劍指offer-二進位制1個數(Java)

文章目錄 問題描述 解析 程式碼 問題描述 請實現一個函式,輸入一個整數,輸出該數二進位制表示中1的個數。例如,把9表示成二進位制是1001,有2位是1。因此,如果輸入9,則該函式輸出為2。 解析 把一個整數減去一,再與原整數做

二進位制1個數 java

二進位制中1的個數 java 題目描述 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 程式碼: public class Solution { public int NumberOf1(int n) { String