[剑指 offer 15] The number of 1s in binary

Please implement a function, input an integer, and output the number of 1s in the binary representation of the number. For example, if 9 is expressed in binary, it is 1001, and 2 bits are 1. Therefore, if you enter 9, the function outputs 2.

Test case 1:

[剑指 offer 15] The number of 1s in binary

Test case 2:
[剑指 offer 15] The number of 1s in binary

Test case 3:
[剑指 offer 15] The number of 1s in binary

First, let’s analyze the problem. If we want to count the number of 1s in the binary system, the first thing we think of is to traverse each bit of this number, then judge it as 1count++, and finally return count. Just write the following code

int hammingWeight(uint32_t n) {
        int count = 0;
        while(n)
        {
            if(n&1)
                count++;

            //此处移位时,如果n为负数可能会导致死循环
            n >>= 1;
        }
        return count;
    }

The above code is correct when counting unsigned numbers, but when counting negative numbers, it may cause an endless loop.
Here we use bit operations instead of division operations, because the efficiency of division in computers is much lower than that of shift operations. We should try our best to replace multiplication and division with shift operators in actual programming.
Let's talk about the negative number of test cases. The characteristic of the right shift operator is that when shifting right by n bits, the rightmost n bits will be discarded. The situation of processing the leftmost bit in the right shift is more complicated. If the number is an unsigned value, the leftmost n bits are filled with 0; if the number is signed, the leftmost n bits are filled with the sign bit of the number. That is to say, if the number was originally positive, then after shifting to the right, add n zeros to the left; if the number was originally negative, then add n 1s to the left after shifting right. Therefore, when the negative number is shifted, the final result is trapped in an endless loop because the highest bit is always complemented by 1. Therefore, the design of the above code is caused by a problem, and we can adjust it.

  • Correct demonstration 1:
int hammingWeight(uint32_t n) {
        int count = 0;
        unsigned int flag = 1;
        while(flag)
        {
            if(n&flag)
                count++;

            flag = flag << 1;
        }
        return count;
    }

In order to avoid infinite loops, here we do not shift the input number n to the right, but bitwise AND n and 1 to determine whether the lowest bit of i is 1, then shift i to the left by 1 bit, and then do bitwise with n And operation. In this way, the number of binary bits 1 in n can be calculated by repeatedly shifting right. The only disadvantage of this solution is that no matter how many 1s there are in the binary digits of n, 32 cycles are required. So can we optimize it? The answer is yes, let’s take a look at the final more perfect answer:
perfect answer:

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

The flexibility of bit operation is reflected in the mechanism here, and it can be seen that the code design is very ingenious and concise. The essence lies in this sentence n = (n-1)&n. Everyone can experience the wonderful pen here.

Guess you like

Origin blog.51cto.com/14289099/2546327