统计一个整数n的二进制表示中1的个数;
分析:此题有多种解法.
1. 除2取余法:求一个整数的二进制的表示是,用的方法是除2取余。对于本题,只是统计一下余数为1的个数而已。
2. 位模式法+移位:1的变种,用移位代除2,该方法更高效。用位模式,与1相与,取得一位。
3. 模式位法: n = n& (n -1); 考虑 n 与 n -1的二进制表示,两者相&, n-1总能将n的最低位的1,置0.
4. 分而治之法:分析,n的二进制表示中位为1的位中1,还可以表示该位的1的个数为1。基于这个计数的性质。
要求一个n位的整数的二进制的表示中1的个数:
(1).若n为1,返回该位的值;即该位上1的个数;
(2) 若n>1时,等于其前n/2位中1的个数+后n/2位中1的个数;
扩展问题一:判断一个整数n是否为2的幂??(tip: if(n && (n & (n-1)) == 0 ) return 1;)即其二进制表示中只有一个1;
int isPowerOf2(unsigned int n) {
if(n && (n & (n-1))== 0) return 1;
return 0;
}
扩展问题二:判断一个整数n是否为4的幂??
分析:一个整数是4的幂,则该数是2的幂,由扩展问题一知,其二进制表示中只有一个1.
而一个数是2的幂未必就是4的幂。一个数是4的幂,满足该数的4进制表示中只有一个1.
即该数的二进制的表示中只有一个1,且该1只能出现在该数的二进制表示2bit组(4进制)的低位,
代码是实现如下:
int isPowerOf4(unsigned int n) {
if(n == 0) return 0;
if(n & (n-1) ) return 0; //不是2的幂;
return n & 0x55555555; //1只能出现在4进制表示的2bit分组的低位
}
通过以上的扩展问题一,二,我们能够设计出判断一个整数n是否2的k次幂p(p= 2^k)的幂。
对于的2的k次幂p(p = 2^k)的整数次幂n,n满足:
《1》n的2进制表示中只有一位为1, 即,n是2的幂;
《2》n的p进制表示中只有一位为1,即,n的二进制表示中,将bits按k位分组,且只有一个k位分组的最低位为1.
具体实现代码及其测试如下:
#include <stdio.h>
#include <assert.h>
int countBitsOf1(int n);
int numOfOnes_0(int n);
int numOfOnes_1(int n);
int numOfOnes_2(int n);
int numOfOnesInDecimalN(int n);
int main(int argc, char *argv[]) {
// printf("%d \n", countBitsOf1(-1));
// printf("%d \n", countBitsOf1(1));
// printf("%d \n", countBitsOf1(0));
// printf("%d \n", countBitsOf1(15));
char i;
for(i = 1; i; ++i) {
assert(numOfOnes_0(i) == countBitsOf1(i));
assert(numOfOnes_1(i) == countBitsOf1(i));
assert(numOfOnes_2(i) == countBitsOf1(i));
printf("number of 1 bit in %d is %d \n", i, countBitsOf1(i));
}
return 0;
}
//统计n的十进制表示中1的个数
int numOfOnesInDecimalN(int n) {
unsigned m = n > 0 ? n : -n;
int count = 0;
while(m) {
if(m%10 == 1) ++count;
m /= 10;
}
return count;
}
//统计n的二进制表示中1的个数:模2取余法
int numOfOnes_0(int n) {
unsigned m = (unsigned)n;
int count = 0;
while(m) {
if(m%2) ++count;
m /= 2;
}
return count;
}
//统计n的二进制表示中1的个数:模2取余法的变种,模式位+移位法
int numOfOnes_1(int n) {
unsigned m = (unsigned)n;
int count = 0;
while(m) {
if(m & 1) ++count;
m >>= 1;
}
return count;
}
//统计n的二进制表示中1的个数:模式位法:n&(n-1) 总能将n的最右边的1置0;
int numOfOnes_2(int n) {
int count = 0;
while(n) {
++count;
n = n & (n-1);
}
return count;
}
//采用分而治之的方法统计n的二进制表示中1的bits
int countBitsOf1(int n) {
n = (n & 0x55555555) + ((n & 0xaaaaaaaa) >> 1); //2bits一组,用2bit表示这个2bit中1的个数
n = (n & 0x33333333) + ((n & 0xcccccccc) >> 2); //4bits一组
n = (n & 0x0f0f0f0f) + ((n & 0xf0f0f0f0) >> 4); //8bits组
n = (n & 0x00ff00ff) + ((n & 0xff00ff00) >> 8); //16bits组
n = (n & 0x0000ffff) + ((n & 0xffff0000) >> 16); //32bits组
return n;
}
测试结果:如下
number of 1 bit in 1 is 1
number of 1 bit in 2 is 1
number of 1 bit in 3 is 2
number of 1 bit in 4 is 1
number of 1 bit in 5 is 2
number of 1 bit in 6 is 2
number of 1 bit in 7 is 3
number of 1 bit in 8 is 1
number of 1 bit in 9 is 2
number of 1 bit in 10 is 2
number of 1 bit in 11 is 3
number of 1 bit in 12 is 2
number of 1 bit in 13 is 3
number of 1 bit in 14 is 3
number of 1 bit in 15 is 4
number of 1 bit in 16 is 1
number of 1 bit in 17 is 2
number of 1 bit in 18 is 2
number of 1 bit in 19 is 3
number of 1 bit in 20 is 2
number of 1 bit in 21 is 3
number of 1 bit in 22 is 3
number of 1 bit in 23 is 4
number of 1 bit in 24 is 2
number of 1 bit in 25 is 3
number of 1 bit in 26 is 3
number of 1 bit in 27 is 4
number of 1 bit in 28 is 3
number of 1 bit in 29 is 4
number of 1 bit in 30 is 4
number of 1 bit in 31 is 5
number of 1 bit in 32 is 1
number of 1 bit in 33 is 2
number of 1 bit in 34 is 2
number of 1 bit in 35 is 3
number of 1 bit in 36 is 2
number of 1 bit in 37 is 3
number of 1 bit in 38 is 3
number of 1 bit in 39 is 4
number of 1 bit in 40 is 2
number of 1 bit in 41 is 3
number of 1 bit in 42 is 3
number of 1 bit in 43 is 4
number of 1 bit in 44 is 3
number of 1 bit in 45 is 4
number of 1 bit in 46 is 4
number of 1 bit in 47 is 5
number of 1 bit in 48 is 2
number of 1 bit in 49 is 3
number of 1 bit in 50 is 3
number of 1 bit in 51 is 4
number of 1 bit in 52 is 3
number of 1 bit in 53 is 4
number of 1 bit in 54 is 4
number of 1 bit in 55 is 5
number of 1 bit in 56 is 3
number of 1 bit in 57 is 4
number of 1 bit in 58 is 4
number of 1 bit in 59 is 5
number of 1 bit in 60 is 4
number of 1 bit in 61 is 5
number of 1 bit in 62 is 5
number of 1 bit in 63 is 6
number of 1 bit in 64 is 1
number of 1 bit in 65 is 2
number of 1 bit in 66 is 2
number of 1 bit in 67 is 3
number of 1 bit in 68 is 2
number of 1 bit in 69 is 3
number of 1 bit in 70 is 3
number of 1 bit in 71 is 4
number of 1 bit in 72 is 2
number of 1 bit in 73 is 3
number of 1 bit in 74 is 3
number of 1 bit in 75 is 4
number of 1 bit in 76 is 3
number of 1 bit in 77 is 4
number of 1 bit in 78 is 4
number of 1 bit in 79 is 5
number of 1 bit in 80 is 2
number of 1 bit in 81 is 3
number of 1 bit in 82 is 3
number of 1 bit in 83 is 4
number of 1 bit in 84 is 3
number of 1 bit in 85 is 4
number of 1 bit in 86 is 4
number of 1 bit in 87 is 5
number of 1 bit in 88 is 3
number of 1 bit in 89 is 4
number of 1 bit in 90 is 4
number of 1 bit in 91 is 5
number of 1 bit in 92 is 4
number of 1 bit in 93 is 5
number of 1 bit in 94 is 5
number of 1 bit in 95 is 6
number of 1 bit in 96 is 2
number of 1 bit in 97 is 3
number of 1 bit in 98 is 3
number of 1 bit in 99 is 4
number of 1 bit in 100 is 3
number of 1 bit in 101 is 4
number of 1 bit in 102 is 4
number of 1 bit in 103 is 5
number of 1 bit in 104 is 3
number of 1 bit in 105 is 4
number of 1 bit in 106 is 4
number of 1 bit in 107 is 5
number of 1 bit in 108 is 4
number of 1 bit in 109 is 5
number of 1 bit in 110 is 5
number of 1 bit in 111 is 6
number of 1 bit in 112 is 3
number of 1 bit in 113 is 4
number of 1 bit in 114 is 4
number of 1 bit in 115 is 5
number of 1 bit in 116 is 4
number of 1 bit in 117 is 5
number of 1 bit in 118 is 5
number of 1 bit in 119 is 6
number of 1 bit in 120 is 4
number of 1 bit in 121 is 5
number of 1 bit in 122 is 5
number of 1 bit in 123 is 6
number of 1 bit in 124 is 5
number of 1 bit in 125 is 6
number of 1 bit in 126 is 6
number of 1 bit in 127 is 7
number of 1 bit in -128 is 25
number of 1 bit in -127 is 26
number of 1 bit in -126 is 26
number of 1 bit in -125 is 27
number of 1 bit in -124 is 26
number of 1 bit in -123 is 27
number of 1 bit in -122 is 27
number of 1 bit in -121 is 28
number of 1 bit in -120 is 26
number of 1 bit in -119 is 27
number of 1 bit in -118 is 27
number of 1 bit in -117 is 28
number of 1 bit in -116 is 27
number of 1 bit in -115 is 28
number of 1 bit in -114 is 28
number of 1 bit in -113 is 29
number of 1 bit in -112 is 26
number of 1 bit in -111 is 27
number of 1 bit in -110 is 27
number of 1 bit in -109 is 28
number of 1 bit in -108 is 27
number of 1 bit in -107 is 28
number of 1 bit in -106 is 28
number of 1 bit in -105 is 29
number of 1 bit in -104 is 27
number of 1 bit in -103 is 28
number of 1 bit in -102 is 28
number of 1 bit in -101 is 29
number of 1 bit in -100 is 28
number of 1 bit in -99 is 29
number of 1 bit in -98 is 29
number of 1 bit in -97 is 30
number of 1 bit in -96 is 26
number of 1 bit in -95 is 27
number of 1 bit in -94 is 27
number of 1 bit in -93 is 28
number of 1 bit in -92 is 27
number of 1 bit in -91 is 28
number of 1 bit in -90 is 28
number of 1 bit in -89 is 29
number of 1 bit in -88 is 27
number of 1 bit in -87 is 28
number of 1 bit in -86 is 28
number of 1 bit in -85 is 29
number of 1 bit in -84 is 28
number of 1 bit in -83 is 29
number of 1 bit in -82 is 29
number of 1 bit in -81 is 30
number of 1 bit in -80 is 27
number of 1 bit in -79 is 28
number of 1 bit in -78 is 28
number of 1 bit in -77 is 29
number of 1 bit in -76 is 28
number of 1 bit in -75 is 29
number of 1 bit in -74 is 29
number of 1 bit in -73 is 30
number of 1 bit in -72 is 28
number of 1 bit in -71 is 29
number of 1 bit in -70 is 29
number of 1 bit in -69 is 30
number of 1 bit in -68 is 29
number of 1 bit in -67 is 30
number of 1 bit in -66 is 30
number of 1 bit in -65 is 31
number of 1 bit in -64 is 26
number of 1 bit in -63 is 27
number of 1 bit in -62 is 27
number of 1 bit in -61 is 28
number of 1 bit in -60 is 27
number of 1 bit in -59 is 28
number of 1 bit in -58 is 28
number of 1 bit in -57 is 29
number of 1 bit in -56 is 27
number of 1 bit in -55 is 28
number of 1 bit in -54 is 28
number of 1 bit in -53 is 29
number of 1 bit in -52 is 28
number of 1 bit in -51 is 29
number of 1 bit in -50 is 29
number of 1 bit in -49 is 30
number of 1 bit in -48 is 27
number of 1 bit in -47 is 28
number of 1 bit in -46 is 28
number of 1 bit in -45 is 29
number of 1 bit in -44 is 28
number of 1 bit in -43 is 29
number of 1 bit in -42 is 29
number of 1 bit in -41 is 30
number of 1 bit in -40 is 28
number of 1 bit in -39 is 29
number of 1 bit in -38 is 29
number of 1 bit in -37 is 30
number of 1 bit in -36 is 29
number of 1 bit in -35 is 30
number of 1 bit in -34 is 30
number of 1 bit in -33 is 31
number of 1 bit in -32 is 27
number of 1 bit in -31 is 28
number of 1 bit in -30 is 28
number of 1 bit in -29 is 29
number of 1 bit in -28 is 28
number of 1 bit in -27 is 29
number of 1 bit in -26 is 29
number of 1 bit in -25 is 30
number of 1 bit in -24 is 28
number of 1 bit in -23 is 29
number of 1 bit in -22 is 29
number of 1 bit in -21 is 30
number of 1 bit in -20 is 29
number of 1 bit in -19 is 30
number of 1 bit in -18 is 30
number of 1 bit in -17 is 31
number of 1 bit in -16 is 28
number of 1 bit in -15 is 29
number of 1 bit in -14 is 29
number of 1 bit in -13 is 30
number of 1 bit in -12 is 29
number of 1 bit in -11 is 30
number of 1 bit in -10 is 30
number of 1 bit in -9 is 31
number of 1 bit in -8 is 29
number of 1 bit in -7 is 30
number of 1 bit in -6 is 30
number of 1 bit in -5 is 31
number of 1 bit in -4 is 30
number of 1 bit in -3 is 31
number of 1 bit in -2 is 31
number of 1 bit in -1 is 32