剑指offer 12. 二进制中1的个数

原题

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

My solution (Wrong)

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        abs_n = abs(n)
        count = 0
        while abs_n != 0:
            abs_n = (abs_n - 1) & abs_n
            count += 1
        return count

答案证明这种方案是错误的,因为 -1 的补码是32,而不是1;
而若是直接使用:

def NumberOf1(self, n):
    count = 0
    while n != 0:
        count += 1
        n = n & (n-1)
    return count

但是!上述代码在n小于0时会无限循环!(Python3.6.1中)
打印n 和 n的二进制表示的值,发现了一个很奇怪的现象。以n=-10举例:
初始时n的二进制值为:

‘0b11111111111111111111111111110110’

循环计数29次后,n的10进制值为:-2147483648,n的二进制值为:

‘0b10000000000000000000000000000000’

循环计数30次后,n的10进制值为:-4294967296,n的二进制值为:

‘0b0’

也就是说,此时虽然n的二进制值为0b0,但是内存中显示n的十进制值为-4294967296,满足 n!=0 的条件, 循环会继续执行。在此之后的循环中,n的二进制表示一直显示为0b0, 但内存中n的十进制数继续不断减少。。。

为什么呢?
我在获取上述n的二进制值时,用的语句是:

print(bin(n & 0xffffffff ))

而直接调用bin语句,会发现:

bin(-10)
'-0b1010'
bin(-12)
'-0b1100'
bin(-16)
'-0b10000'
... ...
bin(-2147483648)
'-0b10000000000000000000000000000000'
bin(-4294967296)
'-0b100000000000000000000000000000000'
bin(-8589934592)
'-0b1000000000000000000000000000000000'
bin(-17179869184)
'-0b10000000000000000000000000000000000'

即在当前情况下,继续循环时n的二进制不断补0,使得n继续不断减小。。。也就是说Python3.6.1中int类型不止32位。。。

问了度娘之后才知道,原来Python2的int类型有32位和64位一说,但到了Python3,当长度超过32位或64位之后,Python3会自动将其转为长整型,长整型理论上没有长度限制。

正确方案

# -*- coding:utf-8 -*-
class Solution:
    def NumberOf1(self, n):
        # write code here
        abs_n = n
        count = 0
        while abs_n & 0xffffffff != 0:
            abs_n = (abs_n - 1) & abs_n
            count += 1
        return count

猜你喜欢

转载自blog.csdn.net/Dby_freedom/article/details/83213746