阳康后的第一篇博客,先来几道恶心二进制编程题
创始人
2024-05-07 04:40:20
0

目录

一、统计二进制中1的个数

二、打印整数二进制的奇数位和偶数位

三、两个整数二进制位不同个数


一、统计二进制中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;
}

四、总结

阳康后第一篇博客,欢迎大佬们指点,后面开始继续输出。加油!!!

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...