剑指offer 11、二进制中1的个数 python和c++

题目描述:

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

思路:

这个在我的个人函数库 简单常用的一些函数,个人的函数库 里面很早就写过,主要是利用 num &= (num - 1); 消掉 num 的二进制表示的最后一个1

没消除一次,不就代表有一个1 吗。c++是肯定过了的,毕竟当初运行测试过。然后在python里面翻车了,原因呢接下来说

c++版

class Solution {
public:
     int  NumberOf1(int n) {
        int count = 0;
        while(n){
            n = n & (n-1);   //消除n的二进制的最后一个1
            count += 1;
        }
        return count;
     }
};

python 翻车版

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        count = 0
        while n:
            n = n & (n-1)   #消除n的二进制的最后一个1
            count += 1
        return count

原因是说超时,我自己在本地测试了一下,发现输入负数就 超时,正数没问题。

查了一下资料,大概是说在Python中,数的大小是可以无限扩大的,那么考虑一下负数,它的符号位其实是在无限远处

举个例子 -1 在计算机里面是 111.....(n个1)...11111111,,这样自然就超时了,所以我们的把负数的位数给限制下

python 没翻车版

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        count = 0
        if n < 0:
            n = n & 0xffffffff  #把负数限定在32位
        while n:
            n = n & (n-1)   #消除n的二进制的最后一个1
            count += 1
        return count

或者

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        count = 0
        for i in range(32):   #把所有的数都限定在32位
            count += (n >> i) & 1    #另一种用右移后和1按位与的方法来计算
        return count

这个 >> 不是带符号的左移吗?为什么可以呢,之前我们不是说python里面数是无穷多位的嘛,其实这是考虑到32位范围内的负数在计算机里面表示的时候,所有的0可能存在的位置都只可能在最右边的32位内,

所以我们限定移位的次数后,保证我们得到是正确答案,但移位31位后的数是个啥就不清楚了,可能是32个1? maybe

所以我们限制了位数是ok的,下面这个也是可行的。

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        count = 0
        for i in range(32):
            count += n & 1
            n = n >> 1
        return count
posted on 2021-06-10 17:17  雾恋过往  阅读(39)  评论(0编辑  收藏  举报

Live2D