python返回参数二进制中1的个数_剑指offer-15二进制中1的个数-python

《剑指offer》python实现系列,全目录

首先介绍位运算:左移相当于乘以2,右移相当于除以2.

n<

100001010<<2=00101000

n>>m,n是正数时,把n右移m位,最右边的m位被丢弃,最左边补n个0。

​ n是负数时,把n右移m位,最右边的m位被丢弃,最左边补n个1.

最初想法:

将数字转为二进制数字,然后统计1的个数。

如何计算二进制?

直接调用python函数,bin(7) = 0b111

1

2

3

4

5

6

7

8

9

10

11

12除2求余,逆序排序

用十进制数除以2,可以得到一个商和余数;将余数保存起来,用商再去除以二,再得到一个商和余数.

反复进行,直到商小于1时结束;然后将之前所得的余数逆序输出,得到的就是该十进制数的二进制

def BinaryEncode(n):

#将n转为二进制,n>0

binarylist=[]

while(n>0):

binarylist.append(n%2)#除2求余

n = n//2

print(binarylist[::-1])#逆序输出

BinaryEncode(11)

在计算负数的二进制表示时,先转为原码,再反码,最后补玛。

Eg:-9的二进制表示是11110111

9的原码是00001001,反码是11110110,补玛是11110111.(最后一位加1)

书上思路:

当n大于0时,将n与1做与运算(如果最右边数字是1与1与运算结果为1)

1

2

3

4

5

6

7

8def NumberOf1(self, n):

mycount = 0

if n > 0:

while n:

if n & 1:#与1做与运算

mycount+=1

n = n>>1 #n右移1位,再进行与运算

return mycount

这个只能解决n大于0的情况,因为n为负数右移m位时,要在最左边补m个1,导致无限循环。

另一种思路:

为避免死循环,不右移数字n,先把n和1与运算,判断最低位是不是1。接着把1左移一位得到2,再和n与运算,判断次低位是不是1…反复将1左移,判断n的其中一位是不是1

1

2

3

4

5

6

7

8

9def NumberOf1(self, n):

mycount = 0

flag = 1

while flag:# 改成 for _ in range(32):

if n&flag:

mycount+=1

flag = flag<<1

return mycount

在 C/C++ 实现时,负整数溢出后为最大整数,但 Python 数值类型(Numeric Type)不会出现溢出的情况,所以,此时,还需要对边界值进行限定。

第三种思路:

有个规律:整数n减去1后,再和原整数n与运算,会将n最右边的1变成0,那么n的二进制表示有多少个1就可以进行多少次操作。

比如1100,减去1为1011,1100与运算1011得到1000,即1100最右边的1变成了0。

1

2

3

4

5

6

7

8def NumberOf1(self, n):

mycount = 0

if n<0:

n = n&0xffffffff

while n:

n = n&(n-1)

mycount+=1

return mycount

1python要使用n & 0xffffffff得到一个负数的补码??这个不太清楚,反正是python的一种机制

第四种方法:

1

2

3

4

5def NumberOf1(self, n):

cnt = 0

if n < 0:

n = n & 0xffffffff

return bin(n).count('1')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值