【蓝桥杯】· 位运算的奇巧淫记及其实战 大家好,我是安然无虞。 【前言】:笔者是根据蓝桥杯官方发布的视频整理出的笔记,博文是由笔记二次整理而来,具有较强的针对性,打算参赛的小伙伴跟着笔者一起行动起来吧!为了方便更多的铁汁们,代码示例中笔者采用的是C语言编写。 【友情提示】:在接下来的两个半月中,博主将会持续推出两个系列的博文,一是零基础搞定C语言,二是蓝桥杯算法竞赛,包括一些刷题感悟与总结哦,当然后面还会有往年的蓝桥杯真题总结,喜欢的铁汁们可以笔者哦。 一、位运算符总结概述 1、按位与 & 如果两个二进制位都为1,则结果是1,否则是0 2、按位或 | 如果两个二进制位都为0,则结果是0,否则是1 3、按位取反 ~ 该位为0,则变为1,否则变为0 4、按位异或 ^ 如果两个数字的二进制位相同,则结果为0,相异则结果为1 5、补充了解移位运算 实际运用当中可以根据情况用左移/右移做快速的乘/除法,这样效率会高很多。 <1>.左移<< 最左侧不要了,最右侧直接补0;(左移相当于乘法,如左移1位,相当于乘以2的1次方) <2>.右移>> 右移相当于除法… 因为C语言中没有特别引入无符号右移,所以C语言中的右移分成算术右移和逻辑右移两种。 算术右移就是最右侧位不要了,最左侧直接补符号位(大多数机器上采用的是算术右移) 所以应用C语言中的右移需要格外注意负数的情况。 逻辑右移就是最右侧不要了,最左侧直接补0 注意:对于int 类型的数据,移位超出32位时,需要模上32,比如1 << 35 == 1 << 3;那么对于long类型来说,超出时需要模上64(模–>求余) <3>.无符号右移>>> 引入Java中的无符号右移,它和左移的用法一直,也就是逻辑右移,最右侧不要了,最左侧补0 6、补充了解原码反码补码 <1>.原码 直接将这个数字按照正负数的形式翻译成二进制即可 <2>.反码 原码的符号位不变,其他位按位取反即可 <3>.补码 反码+1即可得到补码 注意:正数和无符号数的原码、反码、补码都相同,只有求负数的反码、补码才采用上面的计算 声明:对于数据的存储只简单介绍到这里,详细介绍将放在后面零基础搞定C语言系列 二、蓝桥云课:位运算的奇巧淫技 1、判断奇偶数 解题思路:拿int型举例,int占4个字节,也就是32位,对于整型来说,数据存放在内存当中存放的是其补码形式,由于第一位(注意上面图片中第1位的位置)前面的数都是2的1及以上次方,只有当第一位是1时为奇数,是0时为偶数,大家先理解一下上面这句话,明白了以后,如果我们想要判断一个整数的奇偶性,只需要和1进行按位&运算即可,由于1中除第1位以外每一位都是0,又因为任何数中的每一位与1中的0位做&运算,与0位做&运算的位结果都是0,所以偶数和1进行&运算是0,奇数和1进行&运算是1 代码执行: 2、判断二进制位是1还是0(两种方法) 例:int x = 86; // 定义一个整型变量x, 并将其初始化为86,现需要判断第5位是1还是0,该如何操作? 方法一解题思路:老样子,还是用整数1执行操作,由于是判断x的第五位是1还是0,所以取整数1,让1左移(5 – 1)位,也就是左移4位,然后直接和x进行按位&操作,最后再右移4位至该数二进制第一位,若第1位是0,则第5位上的二进制数是0,否则是1 代码执行: 方法二解题思路:该方法较方法一就简单多了,它利用了“判断奇偶数”的解题思想,首先,让x右移(5 – 1)位,即右移4位,然后再和1相&,如果结果是0,则第5位上的二进制数是0,否则是1。 代码执行: 3、交换两个整型变量的值(异或法) 解题思路: 补充:异或,可理解为不进位加法,如1+1 = 0, 0 + 0 = 0, 1 + 0 = 1 异或:如果两个数字的二进制位相同,则结果为0,相异则结果为1. 异或的性质: 1.交换律:可任意交换运算因子的位置,结果不变; 2.结合律: 3.对于任何数x, 都有x ^ x = 0, x ^ 0 = x,同自己求异或为0,同0求异或为自己 4.自反性:A ^ B ^ B = A ^ 0 = A, 连续和同一个因子做异或运算,最终结果为自己 说了这么多,那么位运算中的异或到底跟“交换两个整型变量的值”这个题目有什么联系呢,请听笔者向铁汁们慢慢道来… 例题:int A = 10, int B = 20, 在不引入第3个变量的情况下,交换两个变量的值(除了采用异或法,用加减法也可以,这个将在后面的零基础搞定C语言中详细介绍)
代码执行: 4、不用判断语句,求整数的绝对值 解题思路:
如果上面的表述看不懂也没有关系,表达式已经给出来了,你只需要知道当遇到不用判断语句求整数的绝对值用它即可。 代码执行: 本题采用Java语言编写 三、实战例题 例1、如何找数组中唯一成对的那个数 1-10这10个数放在含有11个素的数组中,只有唯一一个素重复,其他均只出现一次,要求每个数组素只能够被访问一次,请设计一个算法,将它找出来,不用辅助存储空间,能否设计一个算法实现? 解题思路: 想要计算出本题,需要我们掌握异或的性质,思路:定义一个数x,并将它初始化成0,将它和数组中的11个数异或,再和1-10这10个自然数异或,最终的结果就是那个数。 代码执行: 例2、找出落单的那个数 一个数组中除了某一个素中之外,其他的素都出现了两次,请写程序找出这份只出现一次的数字 解题思路: 这道题比第一道题还要简单,直接异或即可 代码执行: 例3、二进制中1的个数 输入一个整数,输出该数二进制表示中1的个数如9的二进制表示为00000000 00000000 00000000 00001001,有两个1 方法1解题思路: 笨方法,把1给数出来–>让1动,那个整数一直不动,利用32次循环,每一次都是将相应位上的数字进行按位&操作 代码执行: 方法2解题思路: 其实就是方法1的一个变形,保持1的位置不动,让那个整数不断右移 代码执行: 方法3解题思路: 技多不压身,铁汁们最好将这三种方法全部掌握,保不准在之后的题目中会用到。 利用循环,当这个整数变为0时循环结束,循环体中执行num = (num – 1) & num 这个操作
可能大家一开始的时候想不到这个解法,笔者也是,我一开始看的时候也很蒙,但是当你看完了之后会有种醍醐灌顶的感觉,说明你理解了原来还可以这样。虽然之前我们可能想不到,但是既然现在遇到了,那就要记住它,以后再出现的时候就要会运用了,一起加油吧铁汁们。 代码执行: 例4、是不是2的整数次方 同一条语句判断一个整数是不是2的整数次方 解题思路: 判断一个整数是不是2的整数次方,也就是这个整数的二进制中只有一个1 代码执行: 看,这里就用到了上一题的方法3,所以我们该不该记住呢… 当你刷题的时候刷到了这题请注意要添加一个条件哦,就是这个num一定是大于0的,因为它是2的幂。 例5、将整数的奇偶位互换 注意:用1做&运算其实就是保留,用0做&运算其实就是消除 解题思路:
代码执行: 思考题:出现K次与出现一次 题目描述:数组中只有一个数出现了1次,其他数都出现了K次,请输出这出现一次的数,需要用位运算,不可以采用暴力求解法。 四、蓝桥结语:遇见蓝桥遇见你,不负代码不负卿! 大学可以说是人生中最美好的阶段,我们虽然有压力,但是相比以后工作、生活而言就算不上什么了,对于身处IT浪潮中的我们而言,愿大家不负韶华,珍惜机会,丰富经历,学有所成。 五、笔者请求 铁汁们,笔者的博文都是由纸质和电子笔记的二次加工而来的,花费了比较多的心力,感觉写的还可以的话,给俺来个点赞,收藏加呗,你们的支持就是笔者最大的动力 准备算法竞赛,或者是想提升基础算法能力的铁汁们都可以订阅哦,免费的啦,周周都有更新。
蓝桥杯常考算法剖析_安然无虞的博客-CSDN博客
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/31929.html