【剑指Offer | C++ 】面试题15:二进制中1的个数 | 判断数字是否2的整数次方 | 两个二进制数的转换最小bit位

24 篇文章 0 订阅
24 篇文章 0 订阅

题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如,把9表示成二进制是1001,有2位是1。因此,如果输入9,则该函数输出2。

初步思路: 数字循环和1 进行与运算( & 1),可以判断数字的最后一位是否为1!

发现问题: 负数右移左边补位为1,会多统计。

如果是正数,可以使用上述方法,加快的循环判断条件为数字为0

为了解决上述问题,
使用辅助数字进行判断,只移动辅助数字,辅助数字移动统计数字的位数
如int为32位,辅助数字必须循环判断32位是否含1

实现代码:

#include<iostream>
using namespace std;

int CountOne(int n) {
    int count = 0;
    int flag = 0b1;
    while (flag) {
        if (flag & n)
            count++;
        flag <<= 1;
    }
    return count;
}

int main()
{
    cout << CountOne(5);
}

更快的解法:
先了解一个规律:数字减一后能将其二进制上最后一位1变为0

(C中0b为二进制,0x为十六进制)
比如二进制
0b10001 - 0b1 = 0b10000
0b11000 - 0b1 = 0b10111

并且最后一个1后面的0全部变成1 100…00 -> 011…11

考虑 与运算 性质
每次将减一后的数字与原数字 与运算 便可得到原数字变最后一个1为0的新数字

同样加速了运算

实现代码:

#include<iostream>
using namespace std;

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

int main()
{
    cout << CountOne(10);
}
  • 拓展思考1:

新方法能够每次把数字最右边的1变为0。
可以用来判断一个数字是否是2的整数次方,如果是,二进制1的个数必为1
一行代码判断:
return !(n & (n - 1));

  • 拓展思考2:

数字一到数字二的数字变化数问题。
如0111 到 1000 需要变化4个bit位

①找到两者数字差别 -> 异或运算 (相当于标记两数不同的位为1)
②重复上述方法便可得到1的数量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赛文X

觉得不错就打赏下呗mua~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值