阅读目录

  • 题目描述
  • 思路和Python实现

题目描述

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

思路和Python实现

  • 首先先解决:负数用补码表示?

  • 在二进制码中,为了区分正负数,采用 最高位 是 符号位 的方法来区分,正数的符号位为0、负数的符号位为1。剩下的就是这个数的绝对值部分,可以采用原码、反码、补码3种形式来表示绝对值部分。

    原码最简单,也最好理解。原码就是绝对值的二进制数形式:例如 +7 的 8位二进制原码是00000111, -7 的8位二进制原码是10000111。

    但对于二进制运算而言,原码的运算不够方便,当两个数相加时,先要判断这两个数的符号是否相同,符号不同的话,还要判断哪一个数的绝对值更大。所以在计算机中,通常都是采用 补码 形式

    正整数的补码与原码形式相同,例如 +7 的8位二进制 补码 是00000111;而负整数的补码则可以通过下列方式得到:将这个负整数的绝对值求反码再加1,连同符号位1一起表示就可以了。例如 -7 的 8位二进制补码:将 -7 的绝对值 7 求反加 1 得 1111001,连同符号位1一起就是11111001。

  • 实际操作一波:
    -2 如何表示呢?
    首先 绝对值 2 的二进制原码 为:0· 000…0010 反码为 1· 111…1101 让它再加 1
    得到 - 2 的补码 就是:1· 111…1110

    再以 -14 举例

    先取绝对值的原码:14 即 00000000 00000000 00000000 00001110

    反码: 11111111 11111111 11111111 11110001

    补码: 11111111 11111111 11111111 11110010

    所以-14 的二进制是 11111111 11111111 11111111 11110010

    假设 得到 二进制要求该整数是多少? 那就是倒着来取相反数

    如二进制是 11111111 11111111 11111111 11110010

    得到反码减1后 11111111 11111111 11111111 11110001

    原码: 00000000 00000000 00000000 00001110

    即 1110 = 14 所以取反 就是 -14

  • 可以推出一种通式 即是 让任意一个整数 n & 0xFFFF FFFF 就能表示出任意一个数在计算机的表示方式!

  • 推算一下其中的原理:因为 int 为带符号类型,带符号类型最高为是符号位,又因为0xFFFFFFFF,也就是四个字节32 bits全是1,符号位是1,所以这个数是负数;F 是 二进制的 15 就是 四位 都是 1111 ,也就是说 当 n 为正整数时,& 32位的 1 ,还是其本身;
    当 n 为负数时,它的二进制表示为补码,可以确定的是,它的符号位一定为1;那么它绝对值的反码+1(补码) & 32位的 1 就能等到 负数的表示方式;如上的 -2 先找到它的补码: 1· 111…1110 & 1111…1111 就能得到 1· 111…1110;
    等等我都晕了,这。。。然后又查找资料说:Python能表示的整数比C/C++大的多,事实上只要你有足够的存储空间python就能表示之,而不象C/C++一般只有一个CPU字大小,Python内部好像都用正数表示整数, 表示负数时只是简单的在前面加个负号,如下↓↓↓

    Python没有unsigned int类型,负数& 0xFFFFFFFF 返回的数就成一个正数
    Python要使用 n & 0xffffffff 得到一个数的补码

思路一:位运算

  • 判断完是否是负数,并对负数进行 n & 0xFFFF FFFF 处理后,就可以开始对二进制中的1的个数进行判断和统计了;接下来是 位运算的巧妙运用了:利用 n&1 和 n>>1这两个位运算。因为1的二进制除了最低位是1,其余位全是0,如果 n&1不为零的话,那么就可以确认 n 当前的最低位就是1,因此可以用 n &1 检测当前最低位是否为1。不断的去判断之前的每一位,n要往右移动一位,将当前位舍弃,直到判断完,即 n 变为0
  • 位运算

(1)<< 左移运算符
将运算对象的 各二进制位 全部左移若干位:符号位不变,低位(右边)补 0

11 << 2 = 44
# 详细过程
00000000 00000000 00000000 00001011
<< 2
00000000 00000000 00000000 00101100 (因为最高位是0,它表示一个正数)
=
44
————————————
-14 <<2 =-56
# 详细过程
11111111 11111111 11111111 11110010 (-14的补码)
<< 2
11111111 11111111 11111111 11001000 (补码)
# 看上面的结果,符号位为1是负数,我们还要将它转换成 原码 才能计算出它的值
11111111 11111111 11111111 11001000 (补码)
11111111 11111111 11111111 11000111 (反码)
10000000 00000000 00000000 00111000 (原码)
# 所以最后结果为:
-56

左移,对于正数来说,左移多少位等于 乘以 2 ^ (左移位数);左移1 相当于乘以2(但效率比乘法高)

(2)>> 右移运算符
将运算对象的 各二进制位 全部 右移若干位:低位溢出,符号位不变,并用符号位补溢出的高位

4 >> 2 = 1
# 详细过程
00000000 00000000 00000000 00000100
>> 2
00000000 00000000 00000000 00000001(因为最高位是0,它表示一个正数)
# 所以最后结果为:
1
————————————
-14 >> 2 = -4
# 详细过程
11111111 11111111 11111111 11110010 (-14的补码)
>> 2
11111111 11111111 11111111 11111100 (补码)
# 看上面的结果,符号位为1是负数,我们还要将它转换成 原码 才能计算出它的值
11111111 11111111 11111111 11111100 (补码)
11111111 11111111 11111111 11111011 (反码)
10000000 00000000 00000000 00000100 (原码)
# 所以最后结果为:
-4

右移,对于正数来说,右移多少位等于 除以 2 ^ (右移位数);右移 1 相当于除以2(效率比除法高哦)

# 左移
class Solution:def NumberOf1(self, n):if n<0:n = n & 0xFFFFFFFFcount=0for i in range(32):mask = 1 << i if n & mask : # 注意这里不能写 成 if n & mask == 1 :count+=1return count
# 右移
class Solution:def NumberOf1(self, n):# write code hereif n<0:n = n & 0xFFFFFFFFcount = 0while n:if n & 1 : # 或者写 if n & 1 ==1: 也行count += 1n = n >> 1 # 不断的重复右移一位return count

判断次数更少,更快,更优的位运算解决方法

  • 如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。

    例如:一个二进制数1010,从右边数起第二位是处于最右边的一个1。减去1后,第二位变成0,它后面的一位0变成了1,而前面的1保持不变,因此得到的结果是1001。即,n减1的结果是把最右边的一个1开始的所有位都取反。

    这个时候如果我们再将 原来的整数 和 减去1之后的整数结果 做 &运算,从原来整数最右边一个1那一位开始所有位都会变成0,其他位保持不变。如1010&1001=1000。

    也就是说,把一个整数n 减去1,再和原整数做与运算,会把该整数最右边一个1变成0,不断做 & 运算,直到 n 最后一次做 & 运算变成 0 ;那么可以进行多少次这样的操作,一个整数的二进制就有多少个1

  • 让 n & (n-1) 具体过程如下图:

class Solution:def NumberOf1(self, n):if n < 0:n = n & 0xFFFFFFFFcount = 0while n:count += 1 # 只要n不为0 就要记录一次,所以要写在前面,开始能进来就不为0n = n & (n-1)return count

剑指offer:Python 二进制中1的个数 0xffffffff是什么意思?相关推荐

  1. 《LeetCode力扣练习》剑指 Offer 15. 二进制中1的个数 Java

    <LeetCode力扣练习>剑指 Offer 15. 二进制中1的个数 Java 一.资源 题目: 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ...

  2. 【LeetCode】剑指 Offer 15. 二进制中1的个数

    [LeetCode]剑指 Offer 15. 二进制中1的个数 文章目录 [LeetCode]剑指 Offer 15. 二进制中1的个数 一.逐位判断 二.巧用 n&(n−1) 一.逐位判断 ...

  3. 剑指 Offer 15. 二进制中1的个数 + 191. 位1的个数(n(n-1)实例)

    一.题目:剑指 Offer 15. 二进制中1的个数 请实现一个函数,输入一个整数(以二进制串形式),输出该数二进制表示中 1 的个数.例如,把 9 表示成二进制是 1001,有 2 位是 1.因此, ...

  4. 剑指 Offer 15. 二进制中1的个数

    /*** 剑指 Offer 15. 二进制中1的个数** Java Integer.bitCount 方法 源码*/public class SolutionJZ15 {public int hamm ...

  5. [剑指Offer]12.二进制中1的个数

    题目 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路 把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样 ...

  6. 剑指Offer #11 二进制中1的个数(想不到的骚操作)

    题目来源:牛客网-剑指Offer专题 题目地址:二进制中1的个数 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 题目解析 对于这种涉及位运算的题目,我们首先要了解基本的位 ...

  7. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h>int wrong_count_1_bits(int n) // 错误解法: ...

  8. 剑指offer: 二进制中1的个数 python 实现

    题目 题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 解题思路 # -*- coding:utf-8 -*- class Solution:def NumberOf1(se ...

  9. 剑指offer——15.二进制中1的个数

    题目: 输入一个整数,输出该数二进制表示中1的个数 知识点: 所有进制数底层都是二进制表示,左位移1位比除二快的多 n = n & (n-1),可以依次从左到右一位一位将1转换成0 位指针左移 ...

  10. 《剑指offer》二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 分析:直接使用java中的Integer自带的把一个整数转为2进制,然后数1的个数就ok(注意charAt返回的是char,用= ...

最新文章

  1. [转]ubuntu系统重新分区、根目录扩容
  2. python list 查找子列_python – SQLAlchemy查询,其中列包含一个子字符串
  3. 【2019暑假刷题笔记-STL绪论】总结自《算法笔记》
  4. 【python基础】用字典做一个小型的查询数据库
  5. 常用jar包_发布Maven包的正确姿势
  6. java摄像头推流,流媒体服务 javaCV-2 推流
  7. 在MAC上如何隐藏文件夹以及查看隐藏文件
  8. 自学考试-“软件开发工具”
  9. SylixOS进化简史
  10. 饮食、生物钟、肠道菌群的“三角恋”
  11. JointJS中文文档
  12. 地理坐标系和投影坐标系
  13. 选择面向 USB4 数据线的 ESD 保护
  14. 学习笔记0521----mysql管理
  15. Android编译源码hook,Hook Android C代码(Cydia Substrate)
  16. windows10和linux双系统安装教程
  17. 汉语字典API接口,免费好用
  18. 考研英语 - word-list-6
  19. 当写烂代码的人离职之后....
  20. CTO:这代码注释让我笑T了。。。

热门文章

  1. 在css中设置font-family:微软雅黑却不生效问题
  2. 读取ES Date从UTC转为北京时间
  3. elementUI:el-upload分片上传大视频到七牛云
  4. 推荐一个加载动图的网站loading.io
  5. Minecraft Skin
  6. 英伟达显卡【NVIDIA GeForece RTX3060 laptop GPU】装深度学习环境,学习框架为Pytorch
  7. 计算机网络之TCP三次握手
  8. 如何使用python寻找K线中的黄昏之星
  9. LAKKA,sx05re等手柄设置错乱,如何重制设置
  10. JDBC编程(JDBC的使用)