位运算小妙招-求二进制序列中1的个数

简介: 位运算小妙招-求二进制序列中1的个数

题目要求

🥩输入一个正整数N,求二进制序列补码中所含1的个数

解法1

🍲 类似于得到十进制数的每一位

image.png

🥫相同的道理,如果我们想知道二进制序列有多少个1,只需要让正整数N不断%2进行判断,使用计数器,统计1的个数,当N为0时,跳出循环

image.png

🍇代码如下

size_t count_bit_one(int n)
{
    size_t count = 0;
    while(n)
    {
        if(n%2 == 1)
        {
            count++;
        }
        n = n/2;
    }
    return count;
}
复制代码

🍤改进: 当我们输入的是负数时,结果会出错,因为整数在内存中以补码形式存储,所以我们可以把参数定义为无符号整数(size_t  即unsigned int) ,这样传参为负数时也不会出错

size_t count_bit_one(size_t n)
{
    size_t count = 0;
    while(n)
    {
        if(n%2 == 1)
        {
           count++;
        }
        n = n/2;
    }
    return count;
}
复制代码

解法2

🥂想办法得到二进制序列中的每一位,这样就要使用到位运算的知识了。

🥨按位与运算& :    0&1 = 0 1&1 = 1    所以我们可以让二进制序列的每一位和1进行与运算,如果对于的二进制序列的位为1,那么结果就是1,反之则是0.


🍷那么我们怎么得到二进制序列中的每一位呢?这里就需要用到右移的知识点了.

右移得到每一位的二进制比特位之后,与1相与进行判断。使用计数器进行计数,如果相与的结果为1,计数器+1

🍮右移:移动的是比特位.


image.png

🍼代码如下

size_t count_bit_one(int n)
{
    int i = 0;
    size_t count = 0;
    for (i = 0; i < 32; i++)
    {
        //n不断右移,对应的二进制位和1相与进行判断,共进行32次
        if (((n >> i) & 1) == 1)
        {
            count++;
        }
    }
    return count;
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    size_t count = count_bit_one(n);
    printf("%d的二进制序列的1的个数为:%u\n", n,count);
  return 0;
}
复制代码

解法3

🍪此处我们要知道n&(n-1)代表什么含义

🥈n&(n-1) :去掉二进制序列中最低位的1  

👢只要知道进行了多少次n&(n-1)运算就知道二进制序列有多少个1


image.png


⚽代码如下

size_t count_bit_one(int n)
{
    size_t count = 0;
    while(n)
    {
        n = n&(n-1);
        count++;
    }
    return count;
}
复制代码

总结

🥼x|(x+1)   : 把二进制序列中最低位的0变成1  可以用此方法统计二进制序列中0的个数,每使用一次,就把低位的0变成1,最后为全1序列、只要统计通过几次使用,值变成-1,就知道二进制序列有多少个0

👕当二进制序列全为1时(补码):代表的值为:-1

👔n&(n-1) : 去掉二进制序列中最低位的比特位1 可以用此方法统计二进制序列中1的个数,每使用一次,就把低位的1变成0,最后为全0序列,只要统计通过几次使用,值变成0,就知道二进制序列有多少个1


相关文章
|
JSON 图形学 数据格式
unity使用TextMeshPro实现聊天图文混排
使用unity也能实现qq好友聊天效果
|
安全 Python
Python Web 开发: 在 Flask 中如何处理文件上传?
Python Web 开发: 在 Flask 中如何处理文件上传?
410 0
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(三)
基于若依ruoyi-nbcio支持flowable流程角色,同时修改流转用户为username,流程启动做大调整(三)
444 1
|
前端开发 JavaScript 测试技术
什么是高阶组件(HOC)?
【8月更文挑战第30天】
308 8
|
前端开发 开发工具 图形学
【你问我答】unity实现一个刮刮乐效果
【你问我答】unity实现一个刮刮乐效果
342 0
|
关系型数据库 C语言 PostgreSQL
PostgreSQL服务端开发学习 -- fmgr.h
fmgr按官方的解释就是Postgres函数管理器和函数调用接口,在使用C语言开发PostgreSQL后端应用时,所以与backend交互时必须遵循fmgr.h中定义的一些规范。
|
消息中间件 Linux API
一篇文章讲明白LinuxKernel编程
一篇文章讲明白LinuxKernel编程
159 0
|
物联网 Python
最近被layerdiffusion分层生成透明图像技术刷屏了!
最近被layerdiffusion分层生成透明图像技术刷屏了!
470 1
|
存储 固态存储 大数据
阿里云服务器收费价格表,云服务器实例、块存储、带宽等项目收费标准参考
阿里云服务器收费项目包括实例价格、预留实例券、专有宿主机、块存储价格、存储容量单位包、带宽价格和快照服务价格,收费模式既有包年包月也有按量付费模式,本文为大家汇总了这些项目的最新收费标准,以供参考。
1054 0
阿里云服务器收费价格表,云服务器实例、块存储、带宽等项目收费标准参考
|
网络协议 NoSQL Linux
使用坦克PWA访问助手为自己的局域网应用快速配置免费域名
这篇教程描述如何使用坦克PWA访问助手。这篇文章简称坦克PWA访问助手为PWA助手。PWA结合了DNS服务器技术和HTTP服务器技术实现,因此它需要系统的**53**端口和**80**端口。
267 0