剑指offer(C++)-JZ15:二进制中1的个数(算法-位运算)

news2024/11/25 11:04:19

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

题目描述:

输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。

数据范围:−2^31<=n<=2^31−1

即范围为:−2147483648<=n<=2147483647

示例:

输入:

10

返回值:

2

说明:

十进制中10的32位二进制表示为0000 0000 0000 0000 0000 0000 0000 1010,其中有两个1。

解题思路:

本题考察位运算。三种解题思路。

1)循环按位比较

       暴力循环,对每个位的1进行统计即可。

2)位运算公式n&(n-1)

       位运算公式n&(n-1),可以将数字最右边的1变为0。比如1011,减一后为1010,与运算得到1010;又比如1010,减一后为1001,与运算得到1000。

       利用该性质进行循环,当n为0后,退出循环停止计数即可。

3)分治法

       以32位1的数字A为例,1111 1111 1111 1111 1111 1111 1111 1111。采用分而治之的思想解题,下面将一步步为大家展示分治法的流程。

3.1)分16组

       32位每两位为一组,设定16组01,再来16组10。

       0x55555555 = 0101 0101 0101 0101  0101 0101 0101 0101

       0xaaaaaaaa = 1010 1010 1010 1010  1010 1010 1010 1010

       与数字A进行与运算可以得到每组中1的个数,比如11和01得到01,11和10得到10,然后10右移1变为01,01+01得到10也就是2,即11中1的个数。

       经过上述计算后,数字A变为A1:1010 1010 1010 1010  1010 1010 1010 1010。

3.2)分8组

       32位每四位为一组,设定8组0011,再来8组1100。

       0x33333333 = 0011 0011 0011 0011  0011 0011 0011 0011

       0xcccccccc = 1100 1100 1100 1100  1100 1100 1100 1100

       与数字A1进行与运算可以得到每组中1的个数,比如1010和0011得到0010,1010和1100得到1000,然后1000右移2变为0010,0010+0010得到0100也就是4,即1111中1的个数。聪明的同学到这里已经发现规律了,可以认为是两组两位数合为一组四位数。

       经过上述计算后,数字A1变为A2:0100 0100 0100 0100  0100 0100 0100 0100。

3.3)分4组

       32位每八位为一组,设定4组0000 1111,再来4组1111 0000。

       0x0f0f0f0f = 0000 1111 0000 1111  0000 1111 0000 1111

       0xf0f0f0f0 = 1111 0000 1111 0000  1111 0000 1111 0000

       与数字A2进行与运算可以得到每组中1的个数,比如0100 0100和0000 1111得到0000 0100,0100 0100和1111 0000得到0100 0000,然后0100 0000右移4变为0000 0100,0000 0100+0000 0100得到0000 1000也就是8,即1111 1111中1的个数。每组数最后的结果其实就是该组数里1的个数。

       经过上述计算后,数字A2变为A3:0000 1000 0000 1000  0000 1000 0000 1000。

3.4)分2组

       32位每十六位为一组,设定2组0000 0000 1111 1111,再来2组1111 1111 0000 0000。

       0x00ff00ff = 0000 0000 1111 1111  0000 0000 1111 1111

       0xff00ff00 = 1111 1111 0000 0000  1111 1111 0000 0000

       与数字A3进行与运算可以得到每组中1的个数,比如0000 1000 0000 1000和0000 0000 1111 1111得到0000 0000 0000 1000,0000 1000 0000 1000和1111 1111 0000 0000得到0000 1000 0000 0000,然后0000 1000 0000 0000右移8变为0000 0000 0000 1000,0000 0000 0000 1000+0000 0000 0000 1000得到0000 0000 0001 0000也就是16,即1111 1111 1111 1111中1的个数。

       经过上述计算后,数字A3变为A4:0000 0000 0001 0000  0000 0000 0001 0000。

3.5)分1组

       32位为一组。

       0x0000ffff = 0000 0000 0000 0000  1111 1111 1111 1111

       0xffff0000 = 1111 1111 1111 1111  0000 0000 0000 0000

       与数字A4进行与运算可以得到每组中1的个数,就是0000 0000 0001 0000加0000 0000 0001 0000等于0000 0000 0010 0000,也就是32。

       之所以用这个数字A,是因为这个数字能很直观地get到这个方法的逻辑。

       经过上述计算后,数字A4变为A5:0000 0000 0000 0000  0000 0000 0010 0000。也就是最终结果。

测试代码:

1)循环按位比较

class Solution {
public:
    // 1的个数
    int  NumberOf1(int n) {
        int count = 0;
        //遍历32位
        for(int i = 0; i < 32; ++i){
            //按位比较
            if((n & (1 << i)) != 0)   
                count++;
        }
        return count;
     }
};

2)位运算公式n&(n-1)

class Solution {
public:
    // 1的个数
    int NumberOf1(int n) {
        int count = 0;
        // 当n为0时停止比较
        while(n){  
            n &= n - 1;
            count++;
        }
        return count;
     }
};

3)分治法

class Solution {
public:
    // 1的个数
    int NumberOf1(int n) {
        int temp = n;
 
        // 0x55555555 = 0101 0101 0101 0101  0101 0101 0101 0101
        // 0xaaaaaaaa = 1010 1010 1010 1010  1010 1010 1010 1010
        temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1);
 
        // 0x33333333 = 0011 0011 0011 0011  0011 0011 0011 0011
        // 0xcccccccc = 1100 1100 1100 1100  1100 1100 1100 1100
        temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> 2);
 
        // 0x0f0f0f0f = 0000 1111 0000 1111  0000 1111 0000 1111
        // 0xf0f0f0f0 = 1111 0000 1111 0000  1111 0000 1111 0000
        temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> 4);
 
        // 0x00ff00ff = 0000 0000 1111 1111  0000 0000 1111 1111
        // 0xff00ff00 = 1111 1111 0000 0000  1111 1111 0000 0000
        temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >> 8);
 
        // 0x0000ffff = 0000 0000 0000 0000  1111 1111 1111 1111
        // 0xffff0000 = 1111 1111 1111 1111  0000 0000 0000 0000
        temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >> 16);
        return temp;
     }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/786178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【运维】DevOps全流程笔记(未完成)

运维笔记 DevOps基本流程Code阶段工具&#xff08;gitlab安装&#xff09;Build阶段工具&#xff08;Maven安装&#xff09;Integrate阶段工具JenkinsJenkins介绍Jenkins安装Jenkins入门配置 CI/CD操作集成Sonar Qube集成HarborJenkins流水线Kubernetes编排工具 DevOps全流程笔…

OJ练习第144题——将数组和减半的最少操作次数

将数组和减半的最少操作次数 力扣链接&#xff1a;2208. 将数组和减半的最少操作次数 题目描述 给你一个正整数数组 nums 。每一次操作中&#xff0c;你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。&#xff08;注意&#xff0c;在后续操作中你可以对减半过的数…

基于YOLOv5的WiderFace人脸检测检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于YOLOv5的WiderFace人脸检测系统可用于日常生活中检测与定位人脸目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的人脸目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练数据集&…

ffplay播放器剖析(6)----音视频同步分析

文章目录 1. 音视频同步基础1.1 音视频同步策略1.2 音视频同步概念1.3 FFmpeg中的时间单位1.4 不同结构体的time_base/duration分析1.5 不同结构体的pts/dts分析1.6 ffplay中Frame结构体分析1.7 Vidoe Frame PTS获取及矫正1.8 Audio Frame PTS的获取 2.以音频为基准3.以视频为基…

了解Unity编辑器之组件篇Tilemap(五)

Tilemap&#xff1a;用于创建和编辑2D网格地图的工具。Tilemap的主要作用是简化2D游戏中地图的创建、编辑和渲染过程。以下是一些Tilemap的主要用途&#xff1a; 2D地图绘制&#xff1a;Tilemap提供了一个可视化的编辑器界面&#xff0c;可以快速绘制2D地图&#xff0c;例如迷…

jlink RTT调试 NRF52840

打开 J-Link RTT Viewer 搜索&#xff1a;**J-Link RTT Viewer ** 软件部分 代码部分 #include <stdbool.h> #include <stdint.h> #include "nrf_delay.h" #include "boards.h" //Log需要引用的头文件 #include "nrf_log.h"…

音频转换工具有很多,但是找到好用的还是得看这篇

在日常生活中&#xff0c;我们常常会遇到需要将音频文件转换成不同格式的情况。不过&#xff0c;有些音频转换软件可能需要安装繁琐的插件&#xff0c;这对于一些小伙伴来说可能不太方便。幸运的是&#xff0c;如今有许多免费的音频转换格式软件可供选择&#xff0c;让我们能够…

K3S 安装部署

一、方法1&#xff1a;利用官方源&#xff08;国外源&#xff09;直接一键安装 因 K3s 的核心组件镜像需从 gcr.io 拉取&#xff08;国内网络不通&#xff09;&#xff0c;所以需具备外网访问的环境&#xff0c;适用于服务器均在国外的环境选用&#xff0c;简单粗暴一键安装。…

mysql进阶1——proxysql中间件

文章目录 一、基本了解二、安装部署三、proxysql管理配置3.1 内置库3.1.1 main库表3.1.2 stats库表3.1.3 monitor库 3.2 常用管理变量3.2.1 添加管理用户3.2.2 添加普通用户3.2.3 修改监听套接字 四、多层配置系统4.1 系统结构4.2 修改变量加载配置4.3 启动加载流程 一、基本了…

聊一聊什么是JNDI数据源

大家好&#xff0c;我是G探险者。 我们平时开发项目&#xff0c;连接数据库那块&#xff0c;会采用连接池的方式连进行连接数据库&#xff0c;比如常见的durid,dbcp&#xff0c;c3p0等。那你有没有听过还有一个JNDI数据源呢&#xff0c;反正我以前是很少听说过。可能就是因为自…

梅尔频谱(Mel spectrum)简介及Python实现

梅尔频谱&#xff08;Mel spectrum&#xff09;简介及Python实现 1. 梅尔频谱&#xff08;Mel spectrum&#xff09;简介2. Python可视化测试3.频谱可视化3.1 Mel 频谱可视化3.2 STFT spectrum 参考文献资料 1. 梅尔频谱&#xff08;Mel spectrum&#xff09;简介 在信号处理上…

wordpress框架自定义添加page分页功能

先来看效果图&#xff1a; 一、在主题目录下的functions.php文件里&#xff0c;添加如下分页函数&#xff1a; /** * 数字分页函数 * 说明&#xff1a;因为wordpress默认仅仅提供简单分页&#xff0c;所以要实现数字分页&#xff0c;需要自定义函数 * Param bool $isHome 是…

工业静电监控系统的功能介绍

工业静电监控系统是一种用于监测和控制工业生产过程中静电现象的技术系统。静电是指由于物体间的电荷不平衡而产生的电场现象&#xff0c;它在工业生产中可能导致电击、火花、电磁干扰等质量问题。 工业静电监控系统主要通过使用静电传感器和控制设备来实现对静电场的监测和控…

Java反序列化(0):URLDNS的反序列化调试分析

URLDNS链子是Java反序列化分析的第0课&#xff0c;网上也有很多优质的分析文章。 笔者作为Java安全初学者&#xff0c;也从0到1调试了一遍&#xff0c;现在给出调试笔记。 一. Java反序列化前置知识 Java原生链序列化&#xff1a;利用Java.io.ObjectInputStream对象输出流的w…

中医药行业如何进行数字化转型?看天津同仁堂谈“有道有术有零代码”

张伯礼院士曾指出&#xff0c;中药制造的现代化水平&#xff0c;还停留在10%左右的阶段。中医药行业&#xff0c;老字号企业&#xff0c;该如何通过数字化焕发新活力&#xff1f; 天津同仁堂通过与伙伴云合作&#xff0c;零代码构建数字化系统&#xff0c;让技术与思维共同成长…

【Linux】Tcp协议的通讯流程,浅谈三次握手四次挥手

文章目录 Tcp协议的通讯流程一、协议定制与网络版计算器的实现二、json的使用总结 Tcp协议的通讯流程 上一篇文章我们讲解了如何实现Tcp服务器&#xff0c;Tcp的接口也用了&#xff0c;下面我们就看一下Tcp协议的通讯流程&#xff1a; 在服务端&#xff0c;我们首先要创建一个…

Django on_delete参数在sql级别操作中不生效问题

class AA(models.Model):name models.CharField(max_length128)class Meta:db_table aaclass BB(models.Model):name models.CharField(max_length128)aa models.ForeignKey(AA, nullTrue, on_deletemodels.CASCADE)class Meta:db_table bb 如上当使用ORM删除aa表中的数据…

数字孪生:未来科技的新前沿

数字孪生作为一项新兴的研究方向&#xff0c;正逐渐成为科技界的焦点。它是将现实世界中的实体、系统或过程通过数字化手段进行建模、仿真和分析&#xff0c;形成与实体相对应的数字化副本。数字孪生的发展为我们带来了无限的想象空间&#xff0c;以及解决现实问题的新途径。 在…

opencv-18 什么是色彩空间?

1.什么是色彩空间类型&#xff1f; 色彩空间类型&#xff0c;也称为颜色空间类型或色彩模型&#xff0c;是一种表示图像中颜色的方式。在计算机图形学和数字图像处理中&#xff0c;有许多种色彩空间类型&#xff0c;每种类型有不同的表达方式和特点。 常见的色彩空间类型包括&a…

Vector - CAPL - 诊断模块函数(回调函数信息)

目录 CanTpCopyDataReceived CAPL 调用返回的错误代码及其含义 CanTpGetReceiverAddress CanTpGetRecentAddressExtension CanTpGetSenderAddress 代码示例 CanTpProvideTxData 代码示例 CanTpSetRxBufferSize 代码示例 CanTpCopyDataReceived 功能&#xff1a;通过回…