劍指offer-二進制中1的個數

題目描述

輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

思路

  • 遇到的問題就是我再一次想把這個數字轉換爲二進制碼,但是其實計算機已經幫我們做了這個過程,轉換爲二進制數其實大多應用於高精度中
  • 鑑於這個情況,我們可以用位運算,從而比較出該數字的每一位1,但是需要注意陷入死循環的問題,只要非空非0,循環就可以一直繼續
  • 至於代碼中設置退出循環的條件就是flag超出unsigned int所能表示的數據範圍,就會發生截斷,然後只保留32位,也就是unsigned int佔4個字節,變成0然後循環退出。

AC代碼

#include <iostream>
#include <math.h>
using namespace std;

class Solution
{
public:
    int NumberOf1(int n)
    {
        int count = 0;
        unsigned int flag = 1;
        int times = 0;
        while (flag)
        {
            if (flag & n)
                count++;
            flag = flag << 1;
            cout << flag << endl;
            times++;
        }
       // cout << "次數爲" << times <<endl;
        return count;
    }
};

int main()
{
    Solution so;

    cout <<so.NumberOf1(13)<<endl;
}

我寫不出來的算法

規律:一個數減去1然後與原來的數進行與運算,會將這個數最右邊的1變成0;(雖然寫不出,但還是學學嘛=-=)這種算法就是一個數裏面有多少個1就循環多少次,

   int NumberOf1_2(int n)
    {
        int count = 0;
        while (n)
        {
            count++;
            n = (n-1) & n;
        }
        return count;
    }

遇到的問題&總結

  • unsigned int與int做運算時,Int會強制轉換爲無符號整數
    unsigned int a = 1,int b = -2;// a b 都是無符號整數 這樣編譯不了,可能是有新版本吧,
    unsigned int a = 1;
    int b = -2;
    int c = -2;
    cout << b << endl;  //-2
    if (a + c > 0)  //因此b,c在計算機中是以補碼的形式存放,0xfffffff(1110)  ==>無符號表示的就是2^32-2
        cout << a + b << endl;  //4294967295  ==>>2^32-1
  • 注意一個變量的類型,無符號整數和有符號整數此外,這個16進制數表示的負數的補碼,正數就無所謂=-=
int res = 0xffffffff;
unsigned int rea = 0xffffffff;
cout << 0xffffffff <<endl;
cout << res <<endl;
cout << rea <<endl;
/*
4294967295
-1
4294967295
*/
  • 遇到判斷二進制數,不用在自己轉爲二進制數了,計算機底層會幫我們處理完成的,只有在高精度時才需要進行這樣的處理
  • 條件判斷只要是不爲0或者不爲空就可以運行
  • 最後一個問題就是左移32或者以上時,編譯器如何處理這個越界情況,上代碼=-=
unsigned int test1 = 2147483648;
test1 = test1 << 1;
cout << "test1: " <<test1 <<endl;
unsigned int test = 1;
test = (test << 32);
unsigned int i = 1;
cout << "test2 :" <<test << endl;
cout <<"test3:" << (i<<32) <<endl;
/*
test1: 0
test2 :1
test3:1
*/

對上述代碼的總結:

  • 首先這個基於g++編譯器
  • 其次,如果對於左移1位的數,越界溢出按照截斷處理(就是隻是保留低位的二進制數)
  • 但是如果左移32或者以上g++編譯器就會默認處理爲:左移位數與該數據類型位數做取模運算,例如無符號整數1 << 32,那麼32 % 32(無符號整數4個字節) = 0,也就是不移動,結果等於1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章