二进制中1的个数
- 参与人数:7224时间限制:1秒空间限制:32768K
- 算法知识视频讲解
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
这本来是一道简单的位移运算题,但是我却做得问题百出,请看代码后的分析。
class Solution {
public:
int NumberOf1(int n) {
int count = 0 ;
unsigned int arg = 1 ;
while ( arg ) {
if ( n & arg ) {
count++ ;
}
arg = arg << 1 ;
}
return count ;
}
};
关于位移有4个概念:逻辑左移、算术左移、逻辑右移、算术右移,这4个东西
比如一个有符号位的8位二进制数11001101,逻辑右移就不管符号位,如果移一位就变成01100110。算术右移要管符号位,右移一位变成10100110。
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关
e.g:1010101010,其中[]位是添加的数字
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
逻辑左移=算数左移,右边统一添0
逻辑右移,左边统一添0
算数右移,左边添加的数和符号有关
e.g:1010101010,其中[]位是添加的数字
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
1.在本题中我们要移动的是arg,而且是循环的左移arg,虽然逻辑左移和算术左移不会出现补1这样的幺蛾子,但是为了严谨起见,我们把arg的类型设置为unsigned int,意为无符号整形。
2.刚开始我的条件判断是这样写的 if ( n & arg == 1 ),,1在这里表示一个二进制数,该数的最低位为1,其余位全为0,仅n的最低位为1且arg的最低位为1是条件成立,这显然
是错误的!
3.arg右移一位时我忘记把右移的值重新赋给arg,直接写的arg << 1; 这也犯了错。
第二次做:
第二次做依然参考了第一次的代码,这里有转换一下思路,输入的参数n不动,对cur做循环左移(算术左移 = 逻辑左移,这是使用左移的主要原因),当cur移动8次后就溢出了,变为0。
class Solution {
public:
int NumberOf1(int n) {
int count = 0 ;
int cur = 1 ;
while ( cur ) {
if ( cur & n ) {
++ count ;
}
cur = cur << 1 ;
}
return count ;
}
};
第三次做:
class Solution {
public:
int NumberOf1(int n) {
int cur = 1 ;
int count = 0 ;
while ( cur ) {
if ( cur & n ) ++ count ;
cur = cur << 1 ;
}
return count ;
}
};