题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示
思路
如果整数不等于0,那么该整数的二进制表示中至少有1位是1。
先假设这个数的最右边一位是1,那么该数减去1后,最右边一位变成了0,其他位不变。
再假设最后一位不是1而是0,而最右边的1在第m位,那么该数减去1,第m位变成0,m右边的位变成1,m之前的位不变。
上面两种情况总结,一个整数减去1,都是把最右边的1变成0,如果它后面还有0,那么0变成1。那么我们把一个整数减去1,与该整数做位运算,相当于把最右边的1变成了0,比如1100与1011做位与运算,得到1000。那么一个整数中有多少个1就可以做多少次这样的运算。
做题可能出现的问题
这里遇到的最大问题就是,如果简单的实现代码的话会出现错误,python中首先明确一点就是二进制没有位数的概念,所以也就无法获得负数真实表示方法
n = -3
n = n & 0xffffffff #n=4294967293
bin(n)#查看二进制形式:'0b11111111111111111111111111111101'
获得的最终结果python会认为是一个正数(因为没有位数的概念,所以首位的1并不代表符号位),那么获得
0b11111111111111111111111111111101
只是形式上和-3的补码相同。
python中,对于负数,无论是右移操作,还是n&(n-1)操作,都会陷入死循环。
所以利用上述这个小技巧,将负数的影响用于0xffffffff相与变为python认为的正数(与机器中的补码相同)。
然后利用正数来进行操作就简单了
python
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
count = 0
if n < 0:
n = n & 0xffffffff
while n:
n = n & (n-1)
count = count+1
return count
C++
class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while (n != 0) {
n = (n - 1) & n;
++count;
}
return count;
}
};