JZ11_二进制中1的个数
知识点:补码、位运算
题目链接
题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
示例1
输入: 10
返回值: 2
解题思路
- 我们需要注意的是 整数包括负数 负数在计算机中是以补码的形式存储的
- 正数的正码、反码和补码都相同
- 负数的补码 = 负数的反码 +1
- 8位的二进制 表示-1 是 1111 1111 因为 1的反码为1111 1110 再加一 是1111 1111
- 注意左移,存在循环左移,负数往右移前面添1
- 所以这道题可以用一个正的0x01 不断左移比较
- 还有一种巧妙的解法,和比当前数减1的与一下。二进制数:val :1101000, val-1: 1100111 那么val & (val-1) : 1100000
代码
#include "cheader.h"
class Solution {
public:
/*
错误代码:
当n是负数的时候,如-1的时候 右移 最高位会补1
int NumberOf1(int n) {
int ans = 0;
while (n != 0) {
if (n & 1)
++ans;
n >>= 1;
}
return ans;
}*/
//让一个数0x01从右向左与val的每一位进行&操作来判断
int NumberOf1(int n) {
int ans = 0;
int mark = 0x01;
while(mark != 0){
if(mark & n)
ans++;
mark <<= 1;
}
return ans;
}
/*
可以对从右向左的第一位1直接判断,遇到0直接略过
现考虑二进制数:val :1101000, val-1: 1100111 那么val & (val-1) : 1100000
*/
int NumberOf1_2(int n) {
int ans = 0;
while(n != 0){
ans ++;
n = n & (n-1);
}
return ans;
}
};
int main()
{
Solution s;
cout<<s.NumberOf1(-1)<<endl;
return 0;
}
今天也是爱zz的一天!