[编程题]统计二进制中1的个数

问题:
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解题思路:
因为负数用补码表示,对于负数右移时,在最高位补得是1,因此负数移位位产生无限个1,陷入死循环。

出现死循环的错误答案:

int NumberOf1_CanNotUse(int n) {
    int count = 0;
    while (n != 0) {
// 用1和n进行位与运算,结果要是为1则n的2进制形式最右边那位肯定是1,否则为0
       if ((n & 1) == 1) {
           count++;
       }
       //把n的2进制形式往右推一位
       n = n >> 1; //负数右移,首位补一,导致无数个1
    }
    return count;
}

答案1:解决负数死循环问题
思想:当n为负数的时候,可以将最高位的符号位1变成0,就是n & 0x7FFFFFFF,这样就把负数转化成正数了,唯一差别就是最高位由1变成0,因为少了一个1,所以count加1。之后再按照while循环里处理正数的方法来操作就可以啦!

int NumberOf1(int n) {
    int count = 0;
    if(n < 0){
        n = n & 0x7FFFFFFF;
        ++count;
    }
    while(n != 0){
        count += n & 1;
        n = n >> 1;
    }
    return count;
}

答案2:用1左移
思想:用1(1自身左移运算,其实后来就不是1了)和n的每位进行位与,来判断1的个数

int NumberOf1_low(int n) {
    int count = 0;
    int flag = 1;
    while (flag != 0) { // 直到1左移超出int范围变为0,要循环32次。
        if ((n & flag) != 0) {
            count++;
        }
        flag = flag << 1;
    }
    return count;
}

答案3:最优解:用(n - 1) & n

int NumberOf1(int n) {
    int count = 0;
    while (n != 0) {
        ++count;
        n = (n - 1) & n;
    }
    return count;
}

引用:
1、题目来源于牛客网:二进制中1的个数
2、答案与解题思路来源于:AlenZhang与writezen

总结:

1、善于利用以为运算符和按位与&。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章