位操作符:与,或,异或 狼羊菜
位操作符
位操作符有三种,即:
①按位与----- &
②按位或----- |
③按位异或-- ^
还有一类操作符叫逻辑操作符,分别为:
①逻辑与----- &&
②逻辑或----- ||
千万不能与按位与(&)和按位或(|)搞混
按位与(&)
int a=5,b=3;
printf("%d\n",a&b);
由于int是4字节,所以a与b的值的二进制分别为
5:00000000 00000000 00000000 00000101
3:00000000 00000000 00000000 00000011
按位与(&)的计算方式为:同为1,方为1
也就是说只有两个位都是1的时候才能是1
即a与b进行按位与运算后输出为
00000000 00000000 00000000 00000001
即为1
按位或(|)
a=5;
b=3;
printf("%d\n",a|b);
此时对ab进行或运算
按位或(|)运算的方式为:遇1则为1
即只要有1 便是1,ab的值的二进制为:
00000000 00000000 00000000 00000101
00000000 00000000 00000000 00000011
运算后为
00000000 00000000 00000000 00000111
即为7
按位异或(^)
a=5;
b=3;
printf("%d\n",a^b);
按位异或(^)的运算方式为:相异为1,相同为0
00000000 00000000 00000000 00000101
00000000 00000000 00000000 00000011
单独提出
101
011
此时前两个位都是相异,第三位为相同,即输出为
00000000 00000000 00000000 00000110
即为6
按位运算的目的:操控位
例:如何将3的第一位控制为0?
int a=3,b=1;
printf("%d\n",a^b);
3的二进制为
00000000 00000000 00000000 00000011
此时要将第一位变成0,即要将3变成
00000000 00000000 00000000 00000010
要想变化,只需让3与1异或,即
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000010
现在不想让第一位变化了,我想让第八位变化,此时需要用到移位的方式,即
a=3;
b=1;
printf("%d\n",a|b<<7);
即让a|b向左位移七位
b=1
00000000 00000000 00000000 00000001
向左位移七位
00000000 00000000 00000000 10000000
此时与a按位或
00000000 00000000 00000000 00000011
00000000 00000000 00000000 10000000
00000000 00000000 00000000 10000011
同样用异或也能解决下面的问题
有一数组c=[3,1,3,2,2],只有一个数只出现了一次,其他的数都出现了两次,请找出出现了一次的数
int c=[3,1,3,2,2];
int i=0;
int ret=0;\\防止数组中只有一个数
while(i<5)
{ret=ret^a[i];i+=1;
}
return 0;
这串代码中,开始ret=0,即为
00000000 00000000 00000000 00000000
此时进入程序,i=0<5,执行while循环
ret^a[0]
00000000 00000000 00000000 00000000
^00000000 00000000 00000000 00000011
ret==00000000 00000000 00000000 00000011 == 3
i=1
ret^a[1]
00000000 00000000 00000000 00000011
^00000000 00000000 00000000 00000001
ret==00000000 00000000 00000000 00000010 ==2
i=2
ret^a[2]
00000000 00000000 00000000 00000010
^00000000 00000000 00000000 00000011
ret==00000000 00000000 00000000 00000001 ==1
i=3
ret^a[3]
00000000 00000000 00000000 00000001
^00000000 00000000 00000000 00000010
ret==00000000 00000000 00000000 00000011 ==3
i=4
ret^a[4]
00000000 00000000 00000000 00000011
^00000000 00000000 00000000 00000010
ret==00000000 00000000 00000000 00000001 ==1
i=5,循环结束,输出为1,也就是数组中单独的数
12.14日更新
如果需要将两个数进行交换,应该怎么做?
想起以前有一个小游戏,一个人要带一只狼一只羊和一捆菜过河,但是船太小了,一次只能送一种东西到对岸去,但是狼和羊在一起时狼会吃羊,羊和菜在一起时羊会吃菜,那么应该怎么办呢?
刚看到这个问题的时候好像还是小学,当时是冥思苦想,不知道该咋办,虽然最大的关注点还是为什么带着狼一块走不会被吃掉,现在想想那狼怕不是是个二哈
言归正传,狼羊菜过河,怎么过?
第一趟:把羊带过去
第二趟:把菜带过去,随后把羊带回来
第三趟:把狼带过去
最后一趟:把羊带过去
即始终要保持狼和菜在同一边并且不能让狼与羊或羊与菜共处
那么回到问题来,想让两个数的位置互换
int main()
{int a = 10,b = 20;return 0;
}
现在有两个数a,b,怎么让他们互换呢
再举个通俗易懂的例子,有两杯水,怎么互换?
很简单,再拿个杯子过来,一杯倒进去,第二杯倒进第一杯,再把原先第一杯的水倒进第二杯,即:
int main()
{int a = 10,b = 20;int c;c = a;a = b;b = c;return 0;
}
是不是跟水倒来倒去很像,改进一下
#include <stdio.h>
#include <stdlib.h>int main()
{int a = 20, b = 10;printf("a = %d, b = %d\n", a, b);int c;c = a;a = b;b = c;printf("a = %d, b = %d\n", a, b);system("pause");return 0;
}
输出看看结果
这样是不是就换成功了
但是这跟位操作符又有什么关系呢?
莫急嘛,马上就来了
如果这个时候我定个条件,你不能多拿个杯子,也就是不能增加变量,你怎么倒?
脑洞一下
把两杯水放进冰箱里边,把它们冻成冰,再进行交换
这也是个好办法,改变他们的形态。但是在c语言里我们应该怎么办呢
此时就需要利用到异或的知识了
前面有提到过,按位异或时相同为 0 相异为 1 ,即两个相同的数在进行异或时会变成 0
这时候就得有大胆的想法了
#include <stdio.h>
#include <stdlib.h>int main()
{int a = 20, b = 10;printf("a = %d, b = %d\n", a, b);a = a^b;b = a^b;a = a^b;printf("a = %d, b = %d\n", a, b);system("pause");return 0;
}
完成,然后就发现自己开始不懂了,这啥玩意,咋就完成了
其实挺好理解的,首先我们需要记住两个相同会抵消
第一步 a = a ^ b
到了第二步 b = a ^ b
此时将 a = a ^ b 代入,即为 b = a ^ b ^ b
两个 b 相消,即 b = a
再到第三步 a = a ^ b
此时在第一步中 a = a ^ b,即 a = a ^ b ^ a
两个 a 相消,即 a = b
完成转换
位操作符:与,或,异或 狼羊菜相关推荐
- 农夫过河狼羊白菜Java开放封闭_农夫过河——狼羊菜问题
话说一位农夫带着一只狼.一只羊和一个卷心菜过河,无奈船小,农夫每次只能运送一样东西,考虑到狼吃羊.羊吃菜,因此运送的顺序至关重要. 在现实世界里解决这个问题并不困难,相信很多人都已经有了答案,但是如何 ...
- 狼羊菜问题的算法思想和C++实现(二进制状态表示 递归状态转移 回溯 剪枝)
狼羊菜问题的算法思想和C++实现 狼羊菜问题 把[狼.羊和蔬菜]这三样东西安全地送至河的对面,你能用的工具只有身边的一艘小船.已知,这艘小船很小,当你坐在里面时,其只能搭载[狼.羊和蔬菜]这三样东西中 ...
- 狼羊菜过河问题深入学习分析——Java语言描述版
前言 这个问题的抛出,是几个星期之前的算法课程.老师分析了半天,最后的结论是:其实就是图的遍历.那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问 ...
- 算法之狼羊菜过河问题
算法之狼羊菜过河问题 1.带羊再带狼 回来时把羊带上 然后把白菜带到对岸 最后把羊带过去 2..带羊再带菜 回来时把羊带上 然后把狼带到对岸 最后把羊带过去 关键点在于羊和两个都有联系,而狼不吃菜,
- 狼羊菜过河(C实现)
题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种 ...
- *python解决狼羊菜过河问题
python解决狼羊菜过河问题 A岸有菜,羊,狼,农夫农夫必须将他们都送到B岸每次只能送一个,在保证他们不会被吃的前提下,完成任务,并得出步骤. 代码: A=[["狼",1],[& ...
- java狼羊草过河_狼羊菜过河问题深入学习分析——Java语言描述版
前言 这个问题的抛出,是几个星期之前的算法课程.老师分析了半天,最后的结论是:其实就是图的遍历.那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问 ...
- 狼羊菜过河问题c语言算法,算法系列之十四:狼、羊、菜和农夫过河问题
题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种方法,让农夫能够 ...
- java狼羊草过河_狼羊菜过河
思路:用0/1代表所处位置,农夫.狼.羊.菜过河就是0000->1111,一共是16种状态,去掉其中的不可能的状态如0011(羊和菜单独一起)是10种. 可以用图的方式表示: 或者用树的方式表示 ...
最新文章
- 如何彻底卸载mysql(xp)
- 实体识别+entity resolution
- Avdshare Audio Converter 7中文版
- .NET开发中应该遵循的几点建议
- Javascript 之 变量
- 用css控制背景图片的位置,大小
- matlab二元一次方程求解_方程的计算机处理913_Matlab
- 用U盘PE启动安装系统教程
- win10本地计算机策略进不去,win10系统gpedit.msc打不开怎么处理 win10本地安全策略打不开...
- 外卖优惠券小程序源码,美团外卖,饿了么外卖红包
- 【大黄蜂打印机cura切片软件配置】
- 安卓手机APP读写高频RFID标签(校园卡)NDEF格式数据设计
- WeBRTC IOS视频采集流程
- 打印机服务器文件,打印机服务器ftp配置文件
- LDO线性稳压电源PCB布局布线
- 用友YonSuite释放商业创新的“蝴蝶效应”
- win10 启动vmware虚拟机就会蓝屏解决方法
- python自动化(三)web自动化:2.web自动化工具selenium讲解
- wden小波滤波函数
- 2020年下半年系统集成项目管理工程师下午真题及答案