【剑指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 服务的教程。当然这个教…

MOTOMAN机器人网络控制的实现

最初程序员在Unix系统下使用Berkeley Socket编写网络程序&#xff0c;随着Windows操作系统的普及&#xff0c;Microsoft、Sun等公司联合开发了Winsock接口API。它实质上是一种进 程间通信&#xff0c;将之从单机环境扩展到网络环境以适合于开发主机/客户机通信程序。网络通信的…

【剑指offer】——【python中return函数中的and和or表达式的返回值】

目录 1、# and 结果为真&#xff0c;返回最后一个表达式的结果&#xff0c;若结果为假返回第一个为假的表达式的结果 2、# or 结果为真&#xff0c;返回第一个为真的表达式的结果&#xff0c;若结果为假&#xff0c;返回最后一个表达式的结果 3、应用[剑指 Offer 64. 求12…n…

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

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

CXF 客服端调用报错

服务端已经发布了WSDL&#xff0c;现在在客服端生成web service客服端代码&#xff0c;在eclipse中新建一个project&#xff0c;然后new->web services->web service client生产客户端代码 在调用的时候报如下错误 解决&#xff1a;缺少axis相应的jar包&#xff0c;加入包…

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

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

做演员是圆梦 做生意学会面对现实

田朴珺是一位拥有多重身份的女性。她是一名演员&#xff0c;也是一位商人&#xff0c;还担任过电影《中国合伙人》的制片人。 作为演员&#xff0c;田朴珺的作品并不是很多&#xff0c;也一直不温不 火。但这并不代表她将放弃演艺生涯。她表示&#xff0c;如果机会合适&…

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

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

第 52 章 Web Server Optimization

系统配置 Intel(R) Xeon(TM) CPU 3.00GHzMemory 4GEthernet adapter 1000M52.1. ulimit 查看 ulimit ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited file size (blocks, -f) unlimited pending signals …

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]从后往…

JS原型链理解

1. 每个对象都有原型属性(__proto__)2. 对象的原型(__proto__)指向其构造函数(Constructor)的prototype属性3. 构造函数(Constructor)的prototype属性本身也是一个对象&#xff0c;其原型(__proto__)亦指向其构造函数的prototype4. 如此形成一个链式结构&#xff0c;而Construc…

【深度学习】——2021年FPN特征金字塔

#!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2021/4/22 17:06 # Author : linlianqin # Site : # File : fpn.py # Software: PyCharm # description:其搭建的基本流程和resnet是一致的&#xff0c;只是将每一层的卷积结果保存了起来import torch impo…

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

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

52.4. APC Cache (php-apc - APC (Alternative PHP Cache) module for PHP 5)

$ apt-cache search php-apc php-apc - APC (Alternative PHP Cache) module for PHP 5$ sudo apt-get install php-apcapc cache 状态监控 http://pecl.php.net/package/APC 下载解包找到apc.php,放到web服务器上 原文出处&#xff1a;Netkiller 系列 手札 本文作者&#xff1…

乐视云计算基于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模型的…

每日站立会议个人博客(冲刺周)-Wednesday

时间未完成不知道如何获取具体标签里的内容正在做爬虫技术之获取标签里的内容将要做对运用爬虫技术获取的数据进行处理转载于:https://www.cnblogs.com/andibier/p/8075098.html

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

第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…