JAVA异或运算符_java位运算符详解

JAVA异或运算符_java位运算符详解目录目录性质应用举例其他用途示例异或是一种基于二进制的位运算,用符号XOR或者^表示,起运算法则是对运算符两侧数的每一个二进制位同值则取0,异值则取1.简单理解就是不进位加法,如1+1=0,0+0=0,1+0=1.性质1、交换律2、结合律(即(a^b)^c==a^(b^c))3、对于任何数x,都有x^x=0,x^0=x4、自反性AXORBXORB=

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

目录


异或是一种基于二进制的位运算,用符号XOR或者^表示,其运算法则是对运算符两侧数的每一个二进制位同值则取0,异值则取1.
简单理解就是不进位加法,如1+1=0,0+0=0,1+0=1.
For example: 3^5 = 6
转成二进制后就是 0011 ^ 0101 二号位和三号位都是异值取1 末尾两个1同值取零,所以3^5 = 0110 = 6

性质

1、交换律
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x^x=0,x^0=x
4、自反性 A XOR B XOR B = A xor 0 = A

异或运算最常见于多项式除法,不过它最重要的性质还是自反性:A XOR B XOR B = A,即对给定的数A,用同样的运算因子(B)作两次异或运算后仍得到A本身。这是一个神奇的性质,利用这个性质,可以获得许多有趣的应用。 例如,所有的程序教科书都会向初学者指出,要交换两个变量的值,必须要引入一个中间变量。但如果使用异或,就可以节约一个变量的存储空间: 设有A,B两个变量,存储的值分别为a,b,则以下三行表达式将互换他们的值 表达式 (值) :
A=A XOR B (a XOR b)
B=B XOR A (b XOR a XOR b = a)
A=A XOR B (a XOR b XOR a = b)

例:

int a = 10, b = 5

a = a ^ b;

b = a ^ b;

a = a ^ b;

类似地,该运算还可以应用在加密,数据传输,校验等等许多领域。

应用举例

1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现
一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空
间,能否设计一个算法实现?
解法一、显然已经有人提出了一个比较精彩的解法,将所有数加起来,减去1+2+…+1000的和。
这个算法已经足够完美了,相信出题者的标准答案也就是这个算法,唯一的问题是,如果数列过大,则可能会导致溢出。
解法二、异或就没有这个问题,并且性能更好。
将所有的数全部异或,得到的结果与1^2^3^…^1000的结果进行异或,得到的结果就是重复数。
但是这个算法虽然很简单,但证明起来并不是一件容易的事情。这与异或运算的几个特性有关系。
首先是异或运算满足交换律、结合律。
所以,1^2^…^n^…^n^…^1000,无论这两个n出现在什么位置,都可以转换成为1^2^…^1000^(n^n)的形式。
其次,对于任何数x,都有x^x=0,x^0=x。
所以1^2^…^n^…^n^…^1000 = 1^2^…^1000^(n^n)= 1^2^…^1000^0 = 1^2^…^1000(即序列中除了n的所有数的异或)。
令,1^2^…^1000(序列中不包含n)的结果为T
则1^2^…^1000(序列中包含n)的结果就是T^n。
T^(T^n)=n。
所以,将所有的数全部异或,得到的结果与1^2^3^…^1000的结果进行异或,得到的结果就是重复数。
当然有人会说,1+2+…+1000的结果有高斯定律可以快速计算,但实际上1^2^…^1000的结果也是有规律的,算法比高斯定律还该简单的多。

google面试题的变形:一个数组存放若干整数,一个数出现奇数次,其余数均出现偶数次,找出这个出现奇数次的数?

@Test
public void fun() {
int a[] = { 22, 38,38, 22,22, 4, 4, 11, 11 };
int temp = 0;
for (int i = 0; i < a.length; i++) {
temp ^= a[i];
}
System.out.println(temp);
}

解法有很多,但是最好的和上面一样,就是把所有数异或,最后结果就是要找的,原理同上!!


其他用途示例

这样可以实现不引人第三个变量实现交换,但是进行的计算相对第三个变量多,所以效率会低一些。
关于其他的方法还有:int a=5,b=10;
a=a+b; //a=15,b=10
b=a-b; //a=15,b=5
a=a-b; //a=10,b=5
但是这样做有一个缺陷,假设它运行在vc6环境中,那么int的大小是4 Bytes,所以int变量所存放的最大值是2^31-1即2147483647,如果我们令a的值为2147483000,b的值为1000000000,那么a和b相加就越界了。
事实上,从实际的运行统计上看,我们发现要交换的两个变量,是同号的概率很大,而且,他们之间相减,越界的情况也很少,因此我们可以把上面的加减法互换,这样使得程序出错的概率减少:
int a=5,b=10;
a -= b; //a=-5,b=10
b += a; //b=5,a=-5
a = b – a; //a=10,b=5
通过以上运算,a和b中的值就进行了交换。表面上看起来很简单,但是不容易想到,尤其是在习惯引入第三变量的算法之后。
它的原理是:把a、b看做数轴上的点,围绕两点间的距离来进行计算。
具体过程:第一句“a-=b”求出ab两点的距离,并且将其保存在a中;第二句“b+=a”求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中;第三句“a+=b”求出b到原点的距离(a到原点距离与ab两点距离之和),并且将其保存在a中。完成交换。

感谢原创作者对知识的分享 转载地址

关于运算符,二进制,位移运算符和运算符的应用介绍的比较详细的博客

下面这两位博主也都写的很好
位运算符的应用1

位运算符的应用2

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185879.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 分布式Session共享解决方案「建议收藏」

    Session是服务器用来保存用户操作的一系列会话信息,由Web容器进行管理。单机情况下,不存在Session共享的情况,分布式情况下,如果不进行Session共享会出现请求落到不同机器要重复登录的情况,一般来说解决Session共享有以下几种方案。1、session复制session复制是早期的企业级的使用比较多的一种服务器集群session管理机制。应用服务器开启web容器的sessi…

  • 全球首款AI芯片_全球AI五强

    全球首款AI芯片_全球AI五强前言你一定听说过CPU、GPU,但是TPU、VPU、NPU、XPU…等等其他字母开头的“xPU”呢?AI概念在几年前火爆全球,科技巨头们纷纷投入AI芯片的研发,小公司也致力于提出概念靠AI浪潮融资,为了快速在AI市场上立足,也为了让市场和用户能记住自家的产品,各家在芯片命名方面都下了点功夫,既要独特,又要和公司产品契合,还要朗朗上口,也要容易让人记住。前文所提到的“xPU”的命名方式就深受各大厂商的喜爱。本文就从字母A到Z来盘点一下目前各种“xPU”命名AI芯片,以及芯片行业里的各种“xPU

    2022年10月28日
  • SQL基础编程_如何学编程

    SQL基础编程_如何学编程一.SQL的环境搭载单机与在线二.SQL的单表操作1.sql基础三步2.sql四则运算3.limit(限制查询结果个数)4.orderby(排序)5.where综合条件筛选6.SQL常量7.distinct(把结果中重复的行删除)8.函数三.SQL的多表操作1.嵌套子循环2.JOIN——连接多个数据库(或多表)3.null与内连接与外连接

  • Linux 下 Mariadb 配置用法

    Linux 下 Mariadb 配置用法

  • idea 2021 mybatis log plugin激活码(注册激活)

    (idea 2021 mybatis log plugin激活码)本文适用于JetBrains家族所有ide,包括IntelliJidea,phpstorm,webstorm,pycharm,datagrip等。https://javaforall.cn/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~F…

  • 102 二叉树层序遍历

    102 二叉树层序遍历层序遍历,每次层的输出是是一个一维数组,整个二叉树的输出结果是二维数组BFS遍历,依托于队列结构,每次在根节点出栈的时候,将其值加在结果列表中,然后将他的左右孩子节点入队列。层序遍历相对于BFS,需要知道每一层有多少个节点。因此,我们需要稍微修改一下代码,在每一层遍历开始前,先记录队列中的结点数量nn(也就是这一层的结点数量),然后一口气处理完这一层的n个结点。classSolution:deflevelOrder(self,root:TreeNode):.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号