题目要求:
🚗求一个二进制序列中二进制位为0的个数
如:15 二进制序列0的个数为28
方法1:%2 /2
二进制:只有0和1 所以我们可以求出二进制1的序列之后,相减
int:4字节->32bit
二进制序列中0的个数 = 32 - 二进制序列1的个数
🛴%2 /2 判断条件不能写成 n%2 == 0 ->count++ 然后返回count的值 因为偶数才符合n%2 == 0
🛵做法:求出二进制序列中1的个数之后,用32-去二进制序列1的个数得到的就是二进制序列中0的个数
size_t Binary_zero(size_t n) { size_t count = 0; while (n) { if (n % 2 == 1) { count++; } n = n / 2; } return 32 - count; } int main() { int n = 0; scanf("%d", &n); size_t ret = Binary_zero(n); printf("%d\n", ret); } 复制代码
🚎注意:当我们输入的是负数时,结果会出错,因为整数在内存中以补码形式存储,如果参数n定义为整形:负数时:会把补码->原码然后再参与下面的计算0的个数,这样就不符合要求! 所以我们可以把参数定义为无符号整数(size_t 即unsigned int),这样传参为负数时也不会出错!
🏍size_t :无符号整数,把内存中的补码当成原码看待
🚠打印16进制时也是把内存中的补码当成原码看待
方法2:得到每一位进行分别判断
🚇将二进制序列的每一个比特位分别判断
🚉**& : 0&1 = 0 1&1 = 1**
所以我们可以让二进制序列的每一位和1进行与运算,如果对于的二进制序列的位为1,那么结果就是1,反之则是0.
🚆右移(>>)得到每一位的二进制比特位之后,与1相与进行判断。使用计数器进行计数,如果相与的结果为1,计数器+1
右移:移动的是比特位.
size_t Binary_zero(int n) { int i = 0; size_t count = 0; for (i = 0; i < 32; i++) { if ( ((n >> i) & 1) == 0) { count++; } } return count; } int main() { int n = 0; scanf("%d", &n); size_t ret = Binary_zero(n); printf("%d\n", ret); } 复制代码
方法3-小妙招:x|(x+1)
✈x|(x+1) : 把二进制序列中最低位的0变成1
可以用此方法统计二进制序列中0的个数,每使用一次,就把内存中的最低位的0变成1,最后为全1序列 ->补码为全1 ->对应十进制值为-1
🚋只要统计通过几次使用,值变成-1,就知道二进制序列有多少个0
所以判断条件为:🚀 while(n != -1)
size_t Binary_zero(int n) { size_t count = 0; while (n != -1) { n = n | (n +1); count++; } return count; } int main() { int n = 0; scanf("%d", &n); size_t ret = Binary_zero(n); printf("%d\n", ret); } 复制代码