剑指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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值