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

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

题目要求:

🚗求一个二进制序列中二进制位为0的个数

如:15 二进制序列0的个数为28


方法1:%2   /2

image.png

二进制:只有0和1 所以我们可以求出二进制1的序列之后,相减


int:4字节->32bit


二进制序列中0的个数 = 32 - 二进制序列1的个数


🛴%2 /2 判断条件不能写成 n%2 == 0 ->count++  然后返回count的值            因为偶数才符合n%2 == 0


🛵做法:求出二进制序列中1的个数之后,用32-去二进制序列1的个数得到的就是二进制序列中0的个数


size_t Binary_zero(size_t n)
{
    size_t count = 0;
    while (n)
    {
        if (n % 2 == 1)
        {
            count++;
        }
        n = n / 2;
    }
    return 32 - count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  size_t ret = Binary_zero(n);
  printf("%d\n", ret);
}
复制代码


🚎注意:当我们输入的是负数时,结果会出错,因为整数在内存中以补码形式存储,如果参数n定义为整形:负数时:会把补码->原码然后再参与下面的计算0的个数,这样就不符合要求!   所以我们可以把参数定义为无符号整数(size_t 即unsigned int),这样传参为负数时也不会出错!


🏍size_t :无符号整数,把内存中的补码当成原码看待

🚠打印16进制时也是把内存中的补码当成原码看待


方法2:得到每一位进行分别判断

image.png

🚇将二进制序列的每一个比特位分别判断

🚉**& :   0&1 = 0 1&1 = 1**

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


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


右移:移动的是比特位.


size_t Binary_zero(int n)
{
  int i = 0;
  size_t count = 0;
  for (i = 0; i < 32; i++)
  {
    if ( ((n >> i) & 1) == 0)
    {
      count++;
    }
  }
  return count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  size_t ret = Binary_zero(n);
  printf("%d\n", ret);
}
复制代码

方法3-小妙招:x|(x+1)


✈x|(x+1)  : 把二进制序列中最低位的0变成1


可以用此方法统计二进制序列中0的个数,每使用一次,就把内存中的最低位的0变成1,最后为全1序列 ->补码为全1 ->对应十进制值为-1


🚋只要统计通过几次使用,值变成-1,就知道二进制序列有多少个0

所以判断条件为:🚀 while(n != -1)


size_t Binary_zero(int n)
{
  size_t count = 0;
  while (n != -1)
  {
    n = n | (n +1);
    count++;
  }
  return count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  size_t ret = Binary_zero(n);
  printf("%d\n", ret);
}
复制代码


相关文章
|
6月前
|
缓存 安全 编译器
C语言「volatile 关键字」:被90%开发者误解的硬件同步原语
`volatile` 是C语言中至关重要的硬件同步原语,核心作用是禁止编译器对变量进行优化:每次读写都必须真实访问内存,确保能感知硬件、中断或其它线程的“意外修改”。它非为多线程而生,却是嵌入式、驱动和底层开发的基石。
1758 4
|
vr&ar 异构计算
最新版PR2023软件安装包Premiere2023永久汉化版下载
Premiere Pro 23.0 版专为帮助编辑人员制作创意内容而设计,提供了出色的字幕工具组合。借助改进功能(如批量编辑时间轴中的标题剪辑、灵活的对齐控件等)简化您的标题和图形工作流程。
3314 0
|
监控 Linux C#
《C#与.NET Core跨平台开发的融合架构与实践逻辑》
本文深入解析了利用C#与.NET Core开发跨平台桌面应用的核心逻辑,探讨如何突破操作系统壁垒实现文件管理、图像处理和系统监控等功能的统一体验。阐述了.NET Core对不同系统底层差异的抽象与适配,包括文件系统规则的转化、图形硬件调用的平衡、系统内核信息的解读,以及C#语言特性在跨平台开发中的互补作用。强调跨平台开发需培养“系统无关”的抽象思维,通过技术融合实现功能逻辑与用户体验的跨平台一致性,重塑桌面应用的开发边界。
330 0
|
大数据 开发者 C++
Python语法糖详解教程
《Python语法糖详解教程》介绍了编程语言中的“语法糖”,即通过特殊语法形式简化代码,使代码更简洁、易读和高效。文章详细解析了列表推导式、字典推导式、元组解包、条件表达式、with语句和装饰器等核心语法糖,并提供了具体示例和最佳实践指南。通过这些技巧,开发者可以在保持底层功能不变的前提下,显著提升开发效率和代码质量。
1359 8
|
机器学习/深度学习 固态存储 计算机视觉
【YOLOv8改进】 RFB (Receptive Field Block):多分支卷积块
**RFB Net是针对目标检测的轻量级解决方案,它通过设计灵感来自人眼感受野的模块提升特征表示。RFB块包含多分支卷积,模拟不同尺度和偏心率,增强轻量模型如SSD的性能。在保持实时速度的同时,RFB Net在准确性上媲美深度检测器。代码可在GitHub找到。**
|
存储 缓存 网络协议
第五问:一个程序从点击到启动发生了什么?
一个可执行程序从用户点击启动到运行,经历了8个主要阶段:用户触发启动、操作系统查找文件、进程创建、可执行文件加载到内存、初始化程序上下文、执行程序入口点、程序运行和程序退出。涉及硬盘、内存、缓存等硬件交互。
|
机器学习/深度学习 搜索推荐 Python
L2范数(L2 norm)
L2范数(L2 norm),也称为欧几里德范数(Euclidean norm)或2-范数,是向量元素的平方和的平方根。它在数学和机器学习中经常被用作一种正则化项、距离度量或误差度量。
12670 76
|
API C# 图形学
程序技术好文:深入理解xLua热更新原理
程序技术好文:深入理解xLua热更新原理
1364 0
|
数据中心 芯片
什么是SFP?SFP的主要特点
【4月更文挑战第21天】
4012 0
什么是SFP?SFP的主要特点
|
算法 C语言
【数据结构】快速排序(4种方式实现)
【数据结构】快速排序(4种方式实现)
733 1