题目:
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
解法一:就是让数字的每一位与1做位运算。
然后有一种做法把输入的的数字不断右移再和1做与运算来判断该位是否为1是错误的。
比如0x80000000,把其右移一位得到的是0xC0000000,不是0x40000000,因为在移位的时候会在高位补充符号位置。
所以应该把1来左移,然后再和原来的数做与运算。
比如判断1110(数字-6)的1的个数,首先1110 & 1 把1左移一位然后与运算
然后1110 & 10(即数字2)
然后1110 & 100
然后1110 & 1000
这样去判断1的个数
C++实现
class Solution {
public:
int NumberOf1(int n) {
int ans = 0;
unsigned int opt = 1;
while(opt)//opt一直左移低位补零,当opt为0结束循环
{
if(n & opt)
ans++;//1的个数增加
opt<<=1;
}
return ans;
}
};
解法二:将一个整数减去1,再和原来整数做与运算,会把最右边的1变成0.有多少个1就可以这样操作多少次
class Solution {
public:
int NumberOf1(int n) {
int ans = 0;
while(n)
{
ans++;
n = (n -1) & n;
}
return ans;
}
};
Python做法
python 太坑了, 输入bin(十进制数)去查看负数的补码之后真是惊呆了。。如下, 居然负数的补码就是正数的原码加了个负号。。。。
>>> bin(1)
'0b1'
>>> bin(-1)
'-0b1'
如果再真的想要得到一个数字的必须得把十进制数字和0xffffffff做与运算
如下
>>>
>>> bin(1 &0xffffffff)
'0b1'
>>> bin(-1 &0xffffffff)
'0b11111111111111111111111111111111' ###转成十六进制之后负数的补码总算正常了。。。
>>>
代码:
所以在python中进行位运算的时候一定把它先转成十六进制再把它进行位运算啊。。。。
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
# write code here
n = n & 0xffffffff
base = 0x1
res = 0
for i in range(32):
if n & base:
res += 1
base <<= 1
# base = base & 0xffffffff
return res