异或运算详解

异或,同0异1,无进位加法

  100
^ 011
= 111

其他:

  • 0^N=N
  • N^N=0
    满足交换律和结合律

经典交换两个数的顺序

a=甲  b=乙

a=a^b  即a=甲^乙
b=a^b  即b=甲^乙 ^乙=甲^(乙^乙)=甲
a=a^b  即a=甲^乙^甲=(甲^甲)^乙=乙

此时
a=乙  b=甲

注意:以上交换,a和b可以是同一个值,但不可以是同一位置,否则双双置为0

怎么说呢,举个栗子

a=甲  b=甲    这是两个不同的位置

a=a^b  即a=甲^甲 
b=a^b  即b=甲^甲  ^甲=甲^(甲 ^甲 )=甲
a=a^b  即a=甲^甲 ^甲=(甲^甲)^甲 =甲 

a=甲  a=甲    这是同一个位置

a=a^a 即a=甲^甲=0 
a=a^a  即a=0^0=0
a=a^a  即a=0^0=0

可明白?

一个数组,其中元素有一个出现奇数次,其余都出现偶数次,找到那个出现奇数次的数

int eor=0;
fori遍历:eor^arr[i]
//相同的元素抵消为0,剩下的数就是那个出现为奇数次的数了

如何把int数的最右侧的1提取出来
a&(~a+1)即可
即a&(-a)

一个数组,里面有两个数出现奇数次,其余出现偶数次

int eor=0;
fori遍历:eor=eor^arr[i]
此时eor为两个出现奇数次的数的异或结果  即 eor=a^b
把eor最右侧的1提取出来
int eor2=eor&(-eor)
此时 eor2为1的位置在 a或b中这一位也为1,且只有一个为1,因为如果都为1,则异或后为0
fori遍历,if eor2^arr[i]!=0  则这个arr[i]为a或b其中一个
比如是a
则b=eor^a

一个数组,里面有一个数出现M次,其余数出现N次,其中N>M

public static void mn(int[]arr){
	//用一个32位的数组累计每个arr[i]的bit位
	int[]bit=new int[32];
	for(int i:arr){
		for(int j=0;j<32;j++){
			if((i>>j)&1!=0){
				bit[j]++;
			}
		}
	}
	int res=0;
	写法1 (我的)
		for(int i=0;i<32;i++){
			bit[i]%=N;
		 if(bit[i]!=0){
			bit[i]/=M;
			res+=Math.power(1,j)
		}	
   写法2  (老师的)
		for(int i=0;i<32;i++){
			res|=1<<i
		}	
      sout res;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值