目录
一、统计二进制中1的个数
二、打印整数二进制的奇数位和偶数位
三、两个整数二进制位不同个数
这是一道牛客网OJ题,感兴趣的话可以先做一遍再看解析哦 -> 牛客网的OJ链接
注意:上面的牛客网是接口型,不需要写主函数,系统默认主函数是存在的,只需要完成函数即可。
题目描述:输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
思路:假设想打印一个整数的十进制的每一位,例如123,我们会先让123%10,得到3,再让123/10,得到12。然后再把12%10,以此类推就能得到它们的每一位,所以总结一下,一个整数的十进制只需循环除10和模10。然而得到二进制的每一位也是如此,只要将二进制循环模2和除2即可。例如:11的二进制为00001011,首先让11%2=1,这个1就是二进制序列上最后一个1,再让11/2=5,5的二进制就是101(就是上面加粗部分)。既然有思路,那我们就来看看怎么写代码吧。
按照上面的思路,不难可以写出这样的代码,但是提交发现代码错误。
举个栗子:当n = -1时,不为0进入循环,-1%2不等于1,cnt不会++,走到n /= 2,带入n的值发现n的结果为0,0为假cnt自然而然就输出0了。说明以上代码对负数是不太友好的。下面有2个办法可以解决改问题。
解决办法1:首先可以把-1当做无符号数来看待,所以只需要在int n前加上unsigned。
解决方法2:可以运用&这个操作符(点我,快速了解操作符)
假设有一个二进制序列为(有32位,简写):00001111,我们&上一个1就能得到最低位的1(加粗),那么问题来了,如何得到其他位上的1呢?这时位移操作符就派上用场了,只需要把00001111右移1位,然后再&上一个1即可。
最后,对于这题,我再为大家展现一个绝妙的解题方法!!
有个表达式是:n = n & (n- 1)
这是一个非常神奇的表达式,当n = 11,它的二进制为1011,n - 1 = 10,它的二进制是1010,1011 & 1010 = 1010(十进制:10),有没有发现,最低位的1不见了;接着,n - 1 = 9,它的二进制为1001,然后再让1010 & 1001 = 1000,这时,最低位的1又不见了。所以,每执行这个表达式,n的二进制最低位上的1都会消失,这个表达式执行几次,就会有多少个1。
对于上面的表达式,还能这么用
假设用编程实现n是否为2的k次方。
思路:只要是2的k次方数字,它们的2进制的表示中只有一个1
例如:2的3次方 ---- 1000
2的2次方 ---- 100
2 的 4次方 ---- 10000
这时就能灵活运用刚刚讲过的表达式:if(n & (n - 1) == 0)
题目内容:获取一个整数二进制序列中所有的偶数位和奇数位,分别打印出二进制序列。
思路:
假设要打印上图中的二进制序列的奇数位和偶数位,那么如何得到它们对应的二进制数字呢?通过上一题也不难发现,只要将(n >> i) & 1即可
代码实现:
#include
void Print(int n)
{printf("奇数位:");int i = 0;for (i = 31; i >= 1; i -= 2){printf("%d ", (n >> i) & 1);}printf("\n");printf("偶数位:");for (int i = 32; i >= 2; i -= 2){printf("%d ", (n >> i) & 1);}printf("\n");
}
int main()
{int n = 0;scanf("%d", &n);Print(n); //封装一个Print函数return 0;
}
描述:输入两个整数,求两个整数二进制格式有多少个位不同(点我,做题!)
思路:先将n和m进行按位异或(^),此时n和m相同的二进制位清零,不同的二进制位为1,最后统计异或后结果的二进制位有几个1即可 。(点我查看操作符详解)
#include
int one(int m,int n)
{int cnt = 0;int tmp = m ^ n;while(tmp){tmp = tmp & (tmp - 1);cnt++;}return cnt;
}
int main()
{int m = 0;int n = 0;scanf("%d %d",&m,&n);int res = one(m,n);printf("%d\n",res);return 0;
}
四、总结
阳康后第一篇博客,欢迎大佬们指点,后面开始继续输出。加油!!!
上一篇:dubbo源码实践-Exchange 信息交换层例子
下一篇:排序算法之快速排序