《剑指offer》第十五题:二进制中1的个数

题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数,例如,把9表示成二进制是1001,有2位是1。如果输入9,输出为2

解法一:

java实现:

int NumberOf1Test01(int n){
int count=0;
while(n>0){
if((n&1)!=0){
count++;
}
n=n>>1;
}
return count;
}
C++实现:
int NumberOf1Test01(int n) {
    int count = 0;
    while (n) {
        if (n & 1) {
            count++;
        }
        n = n >> 1;
    }
    return count;
}
思路:将该数字与1(只有最右面一位数字为1)进行位运算,比较该数字最右面一位数字是否为1,比较完之后将该数字右移一位,继续比较右侧第二个数字,以此类推。
但是,该解法是错误的,错误原因:若该数字是负数,右移会在左面第一位补1,最终导致无限循环。
解法2:
java实现:
int NumberOf1Test02(int n){
int count=0;
int flag=1;
while(flag!=0){
if((count&flag)!=0){
count++;
}
flag=flag<<1;
}
return count;
}
C++实现:
int NumberOf1Test02(int n) {
    int count = 0;
    unsigned int  flag = 1;
    while (flag) {
        if (count & flag) {
            count++;
        }
        flag = flag << 1;
    }
    return count;
}
思路:利用flag和n的各位进行比较,flag为1,和n的右边第一位进行比较,然后flag右移,在和第二位进行比较,以此类推,等到和n的最后一位比较完后,再右移,为0,比较结束。
解法3:
java实现:
int NumberOf1Test03(int n){
int count=0;
while(n!=0){
n=(n-1)&n;
count++;
}
return count;
}
c++实现:
int NumberOf1Test03(int n) {
    int count = 0;
    while (n ) {
        n = (n - 1) & n;
        count++;
    }
    return count;
}
思路:n-1将把n各位中,第一个出现的1变为0,该位右边的各位设成1,和n进行&运算,将把该位右边的1全部化成0(0与1&运算还为0),再赋值给n,将消除一个为1的位,循环该过程,将把1全部消除,求得count。
结论:把一个整数减去1再和原来的整数做位运算,结果将为把该整数最右边的1变成0.


 

 

posted @ 2020-10-23 16:12  第十八使徒  阅读(130)  评论(0)    收藏  举报