判断一个数的二进制数有多少位1

19 篇文章 0 订阅

其实这篇文章可以挖的很深,从二进制的本质出发有很多可以考虑的点。但是我并不能理解这么深55555

从题目中的问题出发,我们将十进制转换为二进制的时候使用的是什么方法呢?

将该数跟2取余,再除于2,反复操作,所有的余数加起来就是目标二进制数。那么统计其中位是1的位只需要在模2的时候记录累加。在将原来的数除以2.代码如下:

#include <iostream>

using namespace std;

// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
    int ret = 0;

    while (number != 0) {
        if (number % 2 == 1)
            ret++;
        number /= 2;
    }

    return ret;
}
// 上述方法只可以检测正数,最负数无可奈何


int main ()
{
    int number;
    cin >> number;
    cout << "Way one is : " << bitNumber (number) << endl;
    cout << "Way two is : " << bitNumber1(number) << endl;
    cout << "Way three is : " << bitNumber2 (number) << endl;
    return 0;
}

上述代码可以基本实现功能,但是如果这个数特别大,时间复杂度就会很高。如果这个数是负数这个方法也不可以使用。

所以为了解决第一个问题我们可以对取余进行改进,将取余改成和1做与运算,除法改成向右进位,其实就是对运算符的改进,不是很好。

#include <iostream>

using namespace std;

// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
    int ret = 0;

    while (number != 0) {
        if (number % 2 == 1)
            ret++;
        number /= 2;
    }

    return ret;
}
// 上述方法只可以检测正数,最负数无可奈何


// 和第一种解法思路差不多,我们一位一位的统计是不是1
// 先判断该数二进制的最后一位是不是1,再将该数向右移动一位
// 判断的方法是通过对数的最后一位进行与运算(只有两个数都是1才是1)
// 让当前数和1进行与运算,1的除最后一位外都是0,所以只会对最后一位检测
int bitNumber1 (int number) {
    int ret = 0;

    while (number != 0) {
        if (number & 1 == 1)
            ret++;
        number = number >> 1;
    }

    return ret;
}
// 上述方法虽然效率高,但是也不能检测负数


int main ()
{
    int number;
    cin >> number;
    cout << "Way one is : " << bitNumber (number) << endl;
    cout << "Way two is : " << bitNumber1(number) << endl;
    cout << "Way three is : " << bitNumber2 (number) << endl;
    return 0;
}

但是这种方法虽然效率上有一点点的改进,不过还是没有解决不能计算负数的问题

所以我们一直对该数和该数减一做与运算,这样知道结果为0就是全部1的个数:

#include <iostream>

using namespace std;

// 通过对数取模运算,余一的就是二进制位为一,将这些统计起来
// 其实这么想的思路就是计算二进制的方法,我们计算二进制的方法不过是把十进制的数字通过对2取余,余数即是二进制数
int bitNumber (int number) {
    int ret = 0;

    while (number != 0) {
        if (number % 2 == 1)
            ret++;
        number /= 2;
    }

    return ret;
}
// 上述方法只可以检测正数,最负数无可奈何


// 和第一种解法思路差不多,我们一位一位的统计是不是1
// 先判断该数二进制的最后一位是不是1,再将该数向右移动一位
// 判断的方法是通过对数的最后一位进行与运算(只有两个数都是1才是1)
// 让当前数和1进行与运算,1的除最后一位外都是0,所以只会对最后一位检测
int bitNumber1 (int number) {
    int ret = 0;

    while (number != 0) {
        if (number & 1 == 1)
            ret++;
        number = number >> 1;
    }

    return ret;
}
// 上述方法虽然效率高,但是也不能检测负数



// 没看懂的方法,写写看
int bitNumber2 (int number) {
    int ret = 0;
    while (number != 0) {
        number = number & (number - 1);
        ret++;
    }
    return ret;
}

int main ()
{
    int number;
    cin >> number;
    //cout << "Way one is : " << bitNumber (number) << endl;
    //cout << "Way two is : " << bitNumber1(number) << endl;
    cout << "Way three is : " << bitNumber2 (number) << endl;
    return 0;
}

各种原因是什么我还要在考虑一下

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值