剑指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