初思路,
/**
* 求一个十进制数的二进制里有多少 1
* 思路:
* n % 2 = 得到的是二进制数的最后一位的值是多少
* 如果不想要最后一位的数,用
* n / 2 = 得到的是将最后以为去掉的数的值
*
* 例子:(取模是得到最后一位的值,相除是去掉最后一位)
* 15 -- 00001111
* 15 % 2 = 1
*
* 15 / 2 = 7 -- 00000111
* 7 % 2 = 1
*
* 7 / 2 = 3 -- 00000011
* 3 % 2 = 1
*
* 3 / 2 = 1 -- 00000001
* 1 % 2 = 1
*
* 1 / 2 = 0
*/
int NumberOf1(int n) {
int count = 0
while (n) {
if (n % 2 == 1) {
count++
}
n /= 2
}
return count
}
int main() {
int n = 1
int ret = NumberOf1(n)
printf("%d\n", ret)
return 0
}
有bug,在 n = -1的时候最后的结果是0,是因为 -1在取模时 -1%2=0-- -1,count不++,然后-1/2=0,然后跳出循环,所以的到的是0.
----------------------------------------------------------------------------------------------------------------------------------------
第二步思想
将传入的函数换成 unsigned int n
所以遵循题目的要求,不符合要求
----------------------------------------------------------------------------------------------------------------------------------------
再次修改,思路是,让 n 向右移动32次,共32位,每一位都 与 1, 得到的是 1,证明,n的这一位是 1
int NumberOf1(int n) {
int count = 0
int i = 0
for (i = 0
if (((n >> i ) & 1) == 1 ) {
count++
}
}
return count
}
----------------------------------------------------------------------------------------------------------------------------------------
另外一种思路
n = n & (n - 1)
设: n = 15
n - 1111
n-1 - 1110
与之后得到n
n - 1110
n-1 - 1101
与之后得到n
n - 1100
n-1 - 1011
与之后得到n
n - 1000
n-1 - 0111
与之后得到n
n - 0000
代码实现
int NumberOf1(int n) {
int count = 0
while (n) {
n = n & (n - 1)
count++
}
return count
}