A description of the number of 1 in binary system
For a variable of one byte (8bit), the number of "1" in the second binary representation requires the algorithm to be executed as high as possible.
"Solution One"
You can give a eight-bit binary example for analysis. For binary operations, we know that by dividing by a 2, the original number will be reduced by a 0. If there is more than one process, then the current position has a 1.
Take 10 100 010 as an example;
The first time divided by 2 o'clock, the quotient is 1 010 001, the remainder is 0.
The second time divided by 2 o'clock, the quotient is 101 000, the remainder is 1.
Therefore, it is possible to consider the characteristics of integer data division and analyze it by dividing and judging the value of the remainder. So we have the following code:
1 Packagechapter2shuzizhimei.erjinzhicount1;2 /**3 * Find the number of 1 in the binary number4 * "Method One"5 * @authorDELL6 *7 */8 Public classCount1 {9 Ten /** One * Statistics integer x is converted to the number of binary 1 A * @paramx number of integers to be computed - * @returnnumber of 1 in binary - */ the Public Static intCountintx) { - intCount = 0;//record the number of 1 in binary - while(x!=0){ - if(x%2==1){ +count++; - } +X/= 2; A } at returncount; - } - - Public Static voidMain (string[] args) { - intx = 15; -System.out.println ("The number of 1 in binary is:" +count (x)); in } -}
The results of the program run as follows:
The number of 1 in binary is: 4
"Solution two" adopts bit operation
The preceding code looks more complex. We know that the right shift operation can also achieve the purpose of dividing. The only difference is how to determine if 1 exists after the shift. For this question, take a look at a eight-bit number: 10 100 001.
In the process of shifting to the right, we will discard the last one directly. Therefore, it is necessary to determine whether the last digit is 1, and the "with" operation can achieve the purpose. This eight-digit number can be manipulated with 00000001. If the result is 1, then the last digit of the current eight-digit number is 1, otherwise 0. The code is as follows:
1 Packagechapter2shuzizhimei.erjinzhicount1;2 /**3 * Find the number of 1 in the binary number4 * "Method two" with bit operation5 * @authorDELL6 *7 */8 Public classCount2 {9 Ten /** One * Statistics integer x is converted to the number of binary 1 A * @paramx number of integers to be computed - * @returnnumber of 1 in binary - */ the Public Static intCountintx) { - intCount = 0;//record the number of 1 in binary - while(x!=0){ -Count + = x&0x01;//use and operation to count the number of 1 +X >>= 1; - } + returncount; A } at - Public Static voidMain (string[] args) { - intx = 15; -System.out.println ("The number of 1 in binary is:" +count (x)); - } -}
The results of the program run as follows:
The number of 1 in binary is: 4
"Solution three" only consider the number of 1
Bit operation is much more efficient than the addition and redundancy operation. However, even with bit operations, the time complexity is still O (log2v) and LOG2V is the number of bits in the binary number. So, can you lower some of the complexity? If there is a way to make the complexity of the algorithm only with the number of "1", the complexity can not be further reduced?
Also use 10 100 001来 for example. If we only consider the correlation with the number of 1, then can we only judge each judgment with one?
To simplify this problem, we consider only one 1 situation. For example: 01 000 000.
How do you tell if a given binary number has only one 1? This can be achieved by judging whether the number is a power of 2 or the whole number. In addition, if only with this one "1" to judge, how to design the operation? What we know is that if you do this, the result is 0 or 1, you can get a conclusion.
If you want the result to be 0, 01 000 000 and 00 111 111 for the and operation.
In this way, the operation to be done is the & (000-00 001) = &00 111 111 = 0.
So there's the code for Solution three:
1 Packagechapter2shuzizhimei.erjinzhicount1;2 /**3 * Find the number of 1 in the binary number4 * "Method three" only consider the number of 1 to reduce the complexity of time5 * @authorDELL6 *7 */8 Public classCount3 {9 Ten /** One * Statistics integer x is converted to the number of binary 1 A * @paramx number of integers to be computed - * @returnnumber of 1 in binary - */ the Public Static intCountintx) { - intCount = 0;//record the number of 1 in binary - while(x!=0){ -x &= (X-1);//eliminate the highest bit of 1 +count++; - } + returncount; A } at - Public Static voidMain (string[] args) { - intx = 15; -System.out.println ("The number of 1 in binary is:" +count (x)); - } -}
The results of the program run as follows:
The number of 1 in binary is: 4
"Solution four" using branch operations
The complexity of solution three is reduced to O (m), where M is the number of 1 in V, maybe someone is already satisfied, only to calculate 1 of the number of digits, this should be fast enough. However, we say that since there are only eight bits of data, simply list the situation of 0~255, and use the branch operation, you can get the answer, the code is as follows:
1 intCountintx)2 { 3 intnum = 0; 4 Switch(x)5 { 6 Case0x0: 7num = 0; 8 Break; 9 Case0x1: Ten Case0x2: One Case0x4: A Case0x8: - Case0x10: - Case0x20: the Case0x40: - Case0x80: -num = 1; - Break; + Case0x3: - Case0x6: + Case0xc: A Case0x18: at Case0x30: - Case0x60: - Case0xc0: -num = 2; - Break; - //... in } - returnnum; to}
The solution four seems very straightforward, but the actual execution efficiency may be lower than the solution two and solution three, because the execution of the branch statement depends on the value of the specific byte, if a = 0, that nature in the 1th case to arrive at the answer, but if a = 255, then in the case of the last one to arrive at the answer, That is, after 255 comparison operations!
It seems that the solution four is not advisable! But the Solution IV provides a way of thinking, that is, the use of space-time method, listed and directly given the value. If you need to get results quickly, you can take advantage of space or take advantage of known conclusions. This is like already know calculate 1+2+ ... +n formula, in the program realization can use the formula to obtain the conclusion.
The method of "solving five" and checking table
The algorithm does not need to make any comparison to return the answer directly, this solution in time complexity should be able to let people gaoshanyangzhi.
The code is as follows:
1 intCOUNTTABLE[256] =2 { 30, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,41, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,51, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,62, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,71, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,82, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,92, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,Ten3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, One1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, A2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, -2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, -3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, the2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, -3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, -3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, -4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 + }; - + intCountintv) A { at returnCounttable[v]; -}
This is a typical space-time algorithm, the number of "1" in the 0~255 is stored directly in the array, V as the subscript of the array, Counttable[v] is the number of "1" in V. The time complexity of the algorithm is only O (1).
In an application that requires frequent use of this algorithm, it is a common method to obtain high time efficiency through " Space Change Time ", and the specific algorithm should be optimized for different applications.
Scaling issues
1. If the variable is a 32-bit DWORD, which of the above algorithms would you use, or which algorithm to improve?
2. Another related question, given the two positive integers (represented in binary form) A and B, asks how many bits (bit) to change a into B? In other words, how many bits in the binary representation of integers A and B are different?
This problem is actually more than the problem 1 a step, as long as the difference between A and B and the result, and then ask the difference or value of 1 in the line.
The 2nd chapter The charm of numbers--the number of 1 in binary system