【剑指offer15.二进制中1的个数】——位操作(左移右移等)

目录

二进制的表示

二进制的位操作

应用: 剑指offer15.统计二进制中1的个数(多种方法,位右移操作、与操作等)


转自:https://www.jianshu.com/p/3a31065a8e58

红色为自己添加

我们都知道在计算机中所有的信息最终都是以二进制的0和1来表示,而有些算法是通过操作bit位来进行运算的,这就需要我们了解Python中如何去表示二进制,又如何是进行位运算的。

二进制的表示

0b111 类型是整型,一般为二进制32整型或者16整型,常见的是二进制8位整型

bin(n)可以将一个十进制或者其他进制的整型转化成二进制,返回的类型是字符串表示的二进制整型

n = 0b101
print(type(n))
print(type(bin(n)))

<class 'int'>
<class 'str'>

首先在Python中可以通过以"0b"或者"-0b"开头的字符串来表示二进制,如下所示

print 0b101 # 输出5
print 0b10  # 输出2
print 0b111 # 输出7
print -0b101 # 输出-5

由此可知我们用二进制表示的数字在打印之后会变成我们更为熟悉的十进制数,更容易被人理解。
当我们需要看十进制数字的二进制表示时,可以使用bin函数

bin(5)  # 输出0b101

二进制的位操作

首先一点需要明确的是所有的运算(包括位操作)在计算机内部都是通过补码形式来进行运算的,关于补码可以参考文章原码,反码和补码,计算机内部运算示意图如下:


此部分转自:https://blog.csdn.net/weixin_39671935/article/details/113980497

先简单说一些概念:

原码:从符号位开始表示,1是正数,0是负数

反码:正数的原码反码补码都是一样的。

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反

比如-5转成二进制原码1101,在算出反码1010

补码:正数的原码反码补码都是一样的。

负数的补码是反码+1


 

 

 

在Python中提供了如下二进制的位操作:

>>  #右移
<<  #左移
|   #位或 
&   #位与
^   #位异或
~   #非

下面我们分别来看下:

左移

0b11 << 2   #输出为12, 即0b1100
5 << 2      #输出为20, 即0b10100
-2 << 2     #输出为-8
5 << 64     #输出为92233720368547758080L
  1. 以0b11为例,0b11的补码就是0b11,所以左移就是将所有的0和1的位置进行左移,移位之后将空位补0。
  2. 负数的左移相对来说就比较复杂,以-2 << 2为例,-2的原码是10000000000000000000000000000010(32位系统),其补码为11111111111111111111111111111110,左移之后变为11111111111111111111111111111000,再转化为原码即10000000000000000000000000001000,也就是-8,也就是-2*(2**2)=-8
  3. 左移超过32位或者64位(根据系统的不同)自动转化为long类型。
  4. 左移操作相当于乘以2**n,以5 << 3为例,相当于5(2*3),结果为40。

右移

0b11 >> 1   #输出为1, 即0b1
5 >> 1      #输出为2,即0b10
-8 >> 3     #输出为-1     
  1. 在Python中如果符号位为0,则右移后高位补0,如果符号位为1,则高位补1;
  2. 同样需要先转化为补码再进行计算,以-8 >> 3为例,-8的原码为10...01000,相应的补码为11...11000,右移后变为1...1,相应的原码为10...01,即-1。
  3. 右移操作相当于除以2**n,8 >> 3相当于8/(2**3)=1

0b110 | 0b101   #输出7,即0b111
-0b001 | 0b101  #输出-1

同样是转化为补码后再进行或运算, 只要有一位有1就为1。
所以或运算常常用于mask技术中的打开开关,即针对某一位把其置为1
比如将某个数字的第三位置为1,我们可以将mask设置为0b100,然后再或运算

mask = 0b100
0b110000 | mask  #turn on bit 3

0b110 & 0b011   #输出2,即0b010

 与运算常常用于mask技术的关闭开关,即针对某一位把其置为0

mask = 0b10
0b111111 & mask  #turn off bit 2

异或

0b111 ^ 0b111   #输出0
0b100 ^ 0b111   #输出3

异或常用于将所有的位反转

0b1010 ^ 0b1111  #输出5,即0b0101

 非

~0b101  #输出2,即0b010
~-3     #输出2

 非运算就是把0变1,1变0,唯一需要注意的是取非时符号位也会变换,比如-3,原码是10...011,补码是11...101,取非后变为00...010,由于符号位为0,所以对应的原码即为其本身,即2。

 

二进制的减法:

设n=0b1010

则n-1=0b1001

减法原则和十进制的减法一致,只是向前借一的时候,一表示的不是10而是2,加法也是一样,满2进1

0b1010
-    1
     =
0b1001

 

应用: 剑指offer15.统计二进制中1的个数(多种方法,位右移操作、与操作等)

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

 

示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

代码实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/5/17 17:59
# @Author  : @linlianqin
# @Site    : 
# @File    : 剑指 Offer 15. 二进制中1的个数.py
# @Software: PyCharm
# @description:
'''
请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数。
例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
''''''
思路:将n变成二进制形式,然后计数'1'的个数
'''
class Solution:def hammingWeight(self, n: int) -> int:return bin(n).count('1')# 将其转化为列表后再诸位变成整数进行相加def hammingWeight1(self,n):return sum(map(int,bin(n)[2:]))n = 0b101
print(Solution().hammingWeight(n))
print(Solution().hammingWeight1(n))# 优化思路,充分利用二进制的位操作
def hammingWeight2(n):# 这里诸位将二进制的数字和1进行运算,若结果为1,则说明当前位置值为1,否则为0count = 0while n: # 当n不全为0时count += n&1 # 这里是进行位与操作,这里的与操作默认是从高位开始的,因此需要进行右移n >>= 1return count
print(hammingWeight2(n))#优化,上述方法进行的是诸位运算,还可以继续优化,巧妙的利用n&n-1,二进制的减法和十进制一样,因此能够检测出最低位的1,即n-1
# n-1会使得最低位的1及后面的0发生变换,1-0,0-1,然后利用n&n-1来更新n,这样来达到计数效果
def hammingWeight3(n):count = 0while n:count += 1n &= n-1return count
print(hammingWeight3(n))
print(type(n))
print(type(bin(n)))

2
2
2
2
<class 'int'>
<class 'str'>

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

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

相关文章

java 异常处理机制(java 编程思想)

一、概念  “异常”这个词有“我对此感到意外”的意思。问题出现了&#xff0c;你也许并不清楚该如何处理&#xff0c;但你的确知道不应该置之不理&#xff1b;你要停下来&#xff0c;看看是不是有别人或在别的地方&#xff0c;能够处理这个问题。只是在当前的环境中还没有足够…

怎样在CentOS 7.0上安装和配置VNC服务器

这是一个关于怎样在你的 CentOS 7 上安装配置 VNC 服务的教程。当然这个教程也适合 RHEL 7 。在这个教程里&#xff0c;我们将学习什么是 VNC 以及怎样在 CentOS 7 上安装配置 VNC 服务器 。 我们都知道 这是一个关于怎样在你的 CentOS 7 上安装配置 VNC 服务的教程。当然这个教…

Spring Cloud构建微服务架构:消息驱动的微服务(入门)【Dalston版】

2019独角兽企业重金招聘Python工程师标准>>> 之前在写Spring Boot基础教程的时候写过一篇《Spring Boot中使用RabbitMQ》。在该文中&#xff0c;我们通过简单的配置和注解就能实现向RabbitMQ中生产和消费消息。实际上我们使用的对RabbitMQ的starter就是通过Spring C…

20145225 《信息安全系统设计基础》第10周学习总结

cp1.c 进行复制文件的操作&#xff0c;需要有源文件和目的文件&#xff0c;第一次命令没有加入所以没有正常完成复制文件的操作fileinfo.c 用来实现显示文件信息。先判断命令是否有操作数&#xff0c;有的话才能继续进行下去&#xff0c;如果没有报错就打印出来相关文件信息&am…

【深度学习】——模型评估指标MAP计算实例计算

目录 一、知识储备 1、IOU——交集面积与并集面积之比 2、混淆矩阵&#xff08;TP、FP、FN、TN&#xff09; 问题1&#xff1a;上面的TP等具体是如何计算得到的&#xff1f; 3、精度precision&召回率recall 二、ap计算实战 1、计算流程 1&#xff09;准备数据&#xf…

hdu5489 Removed Interval dp+线段树优化

现在看这题居然直接秒了。。。去年看的时候还以为神题。。 设以第i项为结尾的lis前缀为f[i]&#xff0c;以第j项为结尾的lis后缀为g[i]&#xff0c;如果求出f[i]和g[j]&#xff0c;然后枚举i&#xff0c;快速找到最大的满足a[j]>a[i]的g[j]就可以了。注意到如果将f[i]从后往…

NoSQL分类及ehcache memcache redis 三大缓存的对比

NoSQL分类 由于NoSQL中没有像传统数据库那样定义数据的组织方式为关系型的&#xff0c;所以只要内部的数据组织采用了非关系型的方式&#xff0c;就可以称之为NoSQL数据库。目前&#xff0c;可以将众多的NoSQL数据库按照内部的数据组织形式进行如下分类&#xff1a; Key/Value的…

乐视云计算基于OpenStack的IaaS实践

本文作者岳龙广&#xff0c;现在就职于乐视云计算有限公司&#xff0c;负责IaaS部门的工作。 从开始工作就混在开源世界里&#xff0c;在虚拟化方面做过CloudStack/Ovirt开发&#xff0c;现在是做以OpenStack为基础的乐视云平台。所以对虚拟化情有独钟&#xff0c;也对虚拟化/云…

【深度学习】——如何提高map值

目录 代码获取 map原理 map提高技巧 技巧总结&#xff1a; 实战&#xff1a; 1、效果不佳map55.55% 1&#xff09;单独调整get_dr_txt.py中的self.iou 0.3 2&#xff09;单独调整get_map,py中的minoverlap: 3)同时调整minoverlap和self.iou 本文是在faster_rcnn模型的…

数据库水平切分的实现原理解析——分库,分表,主从,集群,负载均衡器(转)...

第1章 引言 随着互联网应用的广泛普及&#xff0c;海量数据的存储和访问成为了系统设计的瓶颈问题。对于一个大型的互联网应用&#xff0c;每天几十亿的PV无疑对数据库造成了相当高的负载。对于系统的稳定性和扩展性造成了极大的问题。通过数据切分来提高网站性能&#xff0c;横…

【深度学习】——纠错error: Unable to find vcvarsall.bat:关于安装pycocotools

1、安装包下载 大佬改写支持 Windows 的 COCO 地址&#xff1a;https://github.com/philferriere/cocoapi 下载后如下&#xff1a; 进入pythonAPI 先后运行&#xff1a; python setup.py build_ext --inplacepython setup.py build_ext install 出现以下标志时&#xff0c…

[软件测试airtest软件安装]——填坑

目录 1、安装Python环境&#xff08;版本问题&#xff09; 2、连接手机出现连接上了但是无法进行点击 airtest官网&#xff1a; https://airtest.doc.io.netease.com/for_newer/ 关于软件测试刚入门的可以参考进行了解&#xff1a;https://airtest.doc.io.netease.com/tuto…

KUKA 机器人SPS.SUB程序解析

&ACCESS RVO&COMMENT PLC on controlDEF SPS ( );FOLD DECLARATIONS;FOLD BASISTECH DECL;Automatik externDECL STATE_T STAT定义STATE_T类型的变量。该结构为&#xff1a;STRUC STATE_T CMD_STAT RET1&#xff0c; CMD_STAT是枚举类型数据&#xff0c;组成了STATE_…

jquery validate表单验证插件

1 表单验证的准备工作 在开启长篇大论之前&#xff0c;首先将表单验证的效果展示给大家。 1.点击表单项&#xff0c;显示帮助提示         2.鼠标离开表单项时&#xff0c;开始校验元素    3.鼠标离开后的正确、错误提示及鼠标移入时的帮助提醒 对于初学者而言&…

【Python位运算】——左移操作(<<)右移操作>>

目录 左移操作 右移操作 其他博主的理解 应用——力扣题目78. 子集 解法 深度优先搜索 位运算 参考文献 左移操作 # 左移操作&#xff0c;左移一位相当于乘以b&#xff0c;a<<b,a a*(2^b) print(2<<3) # 2*2^3 16&#xff0c;2的二进制10&#xff0c;向…

sql中字段名中包含特殊字符的查询方法

sql中字段名章包含特殊字符的查询方法&#xff1a;例如包含""&#xff0c;student表中字段为&#xff1a;id“学号”、name"姓名"。 解决办法&#xff1a;用英文下的 ""&#xff08;Tab键上面那个键,不需要shift&#xff09;把字段名包起来。如&…

ABB RAPID SOCKET编程

相传在2009年6月11日&#xff0c;微博的鼻祖t-w-i-t-t-e-r还没有被封锁的时候&#xff0c;于仁颇黎写了了一个东西可以将staubli机器人在运行时的状态&#xff0c;实时发送上去&#xff0c;可以被实时的查看&#xff0c;任何一个人都可以查看&#xff0c;于是就有了这个名为TWI…

机器人 工具坐标系的标定

概念 工具坐标系是把机器人腕部法兰盘所握工具的有效方向定为Z轴&#xff0c;把坐标定义在工具尖端点&#xff0c;所以工具坐标的方向随腕部的移动而发生变化。 工具坐标的移动&#xff0c;以工具的有效方向为基准&#xff0c;与机器人的位置、姿势无关&#xff0c;所以进行相…

Linux内核分析— —计算机是如何工作的(20135213林涵锦)

实验部分 &#xff08;以下命令为实验楼64位Linux虚拟机环境下适用&#xff0c;32位Linux环境可能会稍有不同&#xff09; 使用 gcc –S –o main.s main.c -m32命令编译成汇编代码&#xff0c; int g(int x){ return x 6;} int f(int x){ return g(x);} int main(void){ r…

【测试开发】测试用例讲解

文章目录 目录 文章目录 前言 一、测试用例的基本要素 二、测试用例的设计方法 1.基于需求的设计方法 对日历根据web界面的功能布局分析出的功能框图如下&#xff1a; 继续举一个例子百度云盘非功能测试的案例&#xff1a; 2.等价类 3.边界值 5.正交表 6.场景设计法 7…