剑指offer_第11题_二进制中1的个数

博客主要介绍了如何计算一个整数二进制表示中1的个数,以及补码的概念和计算方法。解释了计算机中使用补码的原因,并通过例子展示了正负整数的补码转换。同时,提出了一个利用按位与操作计算二进制1个数的解题思路。
摘要由CSDN通过智能技术生成

题目描述

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

理解

  • 整数怎么转换为二进制
>>> bin(25)
'0b11001'
>>> bin(25).replace('0b','')
'11001'
  • 什么是补码
    • 计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”。
    • 在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的
    • 一个负整数(或原码)与其补数(或补码)相加,和为模。 对一个整数的补码再求补码,等于该整数自身。
    • n位计算机,设n=8, 所能表示的最大数是11111111,若再加1成为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的模为2^8。在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以了。把补数用到计算机对数的处理上,就是补码。
  • 关于模
    • “模”是指一个计量系统的计数范围。计算机也可以看成一个计量机器,它也有一个计量范围,即存在一个“模”。“模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的余数。任何有模的计量器,均可化减法为加法运算。
    • 在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特性。共同的特点是两者相加等于模。
  • 如何求补码
    求给定数值的补码分以下两种情况:
    • 正整数的补码是其二进制表示,与原码相同
      +9的补码是00001001。(备注:这个+9的补码是用8位2进制来表示的,补码表示方式很多,还有16位二进制补码表示形式,以及32位二进制补码表示形式,64位进制补码表示形式等。每一种补码表示形式都只能表示有限的数字。)
    • 负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0变1,1变0)后加1
      -5对应正数5(00000101)→所有位取反(11111010)→加1(11111011)
  • 转化为原码
    已知一个数的补码,求原码的操作其实就是对该补码再求补码:
    • 如果补码的符号位为“0”,表示是一个正数,其原码就是补码。
    • 如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。
    • 65的补码是10111111
      若直接将10111111转换成十进制,发现结果并不是-65,而是191。
      事实上,在计算机内,如果是一个二进制数,其最左边的位是1,则我们可以判定它为负数,并且是用补码表示。
      若要得到一个负二进制补码的数值,只要对补码全部取反并加1,就可得到其数值。
      如:二进制值:10111111(-65的补码)
      各位取反:01000000
      加1:01000001(+65)
  • 相关概念
    • python中右移左移的定义:右移n位定义为除以pow(2,n),左移n位定义为乘以pow(2,n),而且没有溢出(移除的int会升级为long类型)
    • 把一个整数减去1之后再和原来的整数做按位与,得到的结果相当于是把整数的二进制表示中最右边的一个1变成0

解题思路

思路1

class Solution:
    def NumberOf1(self, n):
        if n>=0:
            count = bin(n).count('1')
        else:
            n=abs(n)
            count = 32 - bin(n-1).count('1')
        return count

思路2
python要使用n & 0xffffffff得到一个数的补码

class Solution:
    def NumberOf1(self, n):
        if n < 0:
            n = n & 0xffffffff
        return bin(n).count('1')

思路3

class Solution:
    def NumberOf1(self, n):
        # write code here
        count=0;
        for i in range(0,32):
            if n&1:
                count=count+1
            n=n>>1
        return count

思路4

注意到每个非零整数n和n-1进行按位与运算,整数n的二进制数中最右边的1就会变成0,那么二进制数中的1的个数就会减少一个,因此可以利用一个循环,使得 n = n&(n-1) ,计算经过几次运算减少到0,就是有几个1。

class Solution:
    def NumberOf1(self, n):
        cnt = 0
        if n < 0:
            n = n & 0xffffffff
        while n:
            n =  n & (n - 1)
            cnt += 1
        return cnt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值