求二進位制中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.基於這種思路,程式碼如下:
這種解決方法看起來還不錯,不過還是有比它更高效的方法,那就是整數有多少個1就迴圈多少次。我們的實現方法是:把一個整數減去1,再和原整數做與運算,會把該整數最右邊一個1變為0,那麼一個整數的二進位制表示中有多少個1就可以進行多少次這樣的操作。基於這種思路,我們可以寫下如下的程式碼://int Count(int n) //{ // int count = 0; // unsigned int flag = 1; // while(flag) // { // if(n & flag) // { // count++; // } // flag = flag << 1; // } // return count; //}
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的個數。
#include<iostream> #include<stdlib.h> using namespace std; int Number1(int n) { int
位運算--求一個 數二進位制中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