transferred from: http://zhedahht.blog.163.com/blog/static/2541117420073118945734/
Author: Huang
originating from: http://zhedahht.blog.163.com/
Title: Enter an integer to find out how many 1 are in the binary representation of the integer. For example, enter 10, because the second binary is represented as 1010, there are two 1, so the output is 2.
Analysis: This is a very basic test of bit arithmetic. Many companies, including Microsoft, have used the problem.
A very basic idea is that we first determine whether the rightmost bit of an integer is 1. Then move the integer to the right, the second digit on the right is now moved to the first position, and then judge is not 1. This moves one bit at a time until the integer becomes 0. Now the question becomes how to judge whether the rightmost bit of an integer is 1. Very simple, if it and integer 1 are made with the operation. Since 1 all other bits are 0 except for the rightmost bit. So if the result of the operation is 1, the rightmost one of the integers is 1, otherwise it is 0.
The resulting code is as follows:
///////////////////////////////////////////////////////////////////////
Get how many 1s in an integer ' s binary expression
///////////////////////////////////////////////////////////////////////
int numberof1_solution1 (int i)
{
int count = 0;
while (i)
{
if (I & 1)
Count + +;
i = i >> 1;
}
return count;
}
Some readers may ask that the integer right shift one is mathematically and divided by 2 is equivalent. Could you replace the right-shift operator in the above code with the 2? The answer is better not to divide. Because the efficiency of division is much lower than the shift operation, in practical programming, if possible, the shift operator should be used instead of the multiplication method.
The idea is that when input i is positive, there is no problem, but when I is a negative number, not only does not get the correct 1, but also causes a dead loop. Taking a negative 0x80000000 as an example, when you move right one bit, it is not simply to move the top bit 1 to the second position into the 0x40000000, but 0xc0000000. This is because the shift is a negative number before the shift is still guaranteed to be a negative number, so the highest position after the shift is set to 1. If you do a right-shift operation, the number will eventually become 0xFFFFFFFF and fall into a dead loop.
To avoid a dead loop, we can not move the input number I right. First I and 1 do with an operation, which determines whether the lowest bit of I is not for 1. Then the 1 left one get 2, and I do and the operation, you can judge I is the sub-high is 1 ... This way, you can judge if one of I is 1. Based on this, we get the following code:
///////////////////////////////////////////////////////////////////////
//Get how many 1s in an integer ' s Binary expression
///////////////////////////////////////////////////////////////////////
int Numberof1_solution2 (int i)
{
int count = 0;
unsigned int flag = 1;
while (flag)
{
if (I & Flag)
count + +;
flag = flag << 1;
}
return count;
}
Another idea is that if an integer is not 0, then at least one of the integers is 1. If we subtract this integer by 1, then the 1 at the far right of the integer will become 0, and all 0 after 1 will become 1. All remaining bits will not be affected. For example: A binary number 1100, the third digit from the right number is the one on the rightmost 1. After subtracting 1, the third bit becomes 0, the two bit 0 behind it becomes 1, and the preceding 1 remains the same, so the result is 1011.
We found that the result of minus 1 was to reverse all the bits starting from the rightmost 1. This time if we do the original integer and minus 1 after the result of the operation, from the original integer to the right of the first 1 that the beginning of all the bits will become 0. such as 1100&1011=1000. That is, subtracting an integer by 1, and then doing and arithmetic with the original integer will change the rightmost 1 of the integer to 0. Then the number of binary numbers of an integer is 1, so how many times such operations can be performed.
This idea corresponds to the following code:
///////////////////////////////////////////////////////////////////////
//Get how many 1s in an integer ' s Binary expression
///////////////////////////////////////////////////////////////////////
int Numberof1_solution3 (int i)
{
int count = 0;
while (i)
{
++ count;
i = (i-1) & I;
}
return count;
}