关于异或的一些操作

异或 ^

相同为0,不同为1 同或则刚好相反

// 0101001             111001        111001

// 1001010              111001        000000

// 1100011 000000 111001

可以理解为无进制加法,即忽略进位的加法

异或操作满足分配律和结合律

实现两数交换可以使用异或

int a = 3. b = 4

a = a^b;

b = a^b;

a = a^b;

此时,a和b的值已经交换

例题:在一个数组中只有a出现了奇数次,其余数字都出现了偶数次,请找出这个a;

int [] arr = new int [n];

int eor = 0;

for(int i = 0 ; i < arr.length;i++){

        eor ^=arr[i];

}

//此时eor就是a 因为奇数次异或等于本身,偶数次异或等于0

System.out.println(eor);

如果有一个不为0的数a,需要提取出其二进制中最右边的一个1

a &(~a + 1)

//000110010000

~a  =         111001101111

~a +1 =     111001110000

a&(~a +1)  00000010000

如果一个数组中有a和b两个数字出现了奇数次 其余均出现了偶数次,需要找出a和b

首先跟一个奇数次一样定义eor = 0,循环异或数组中的所有元素,此时eor = a^b !=0;即eor中总有1位不为0,可用提取最右边1位1的方法找出这一位s,然后将数组分为两部分,一部分位s位位0,一部分为s位为1的,此时a和b一定在不同的两个部分,随机找一部分,定义eor' = 0,eor'循环与这一部分的所有数据异或得到的就是这个奇数次的数字a或b

则我们需要的就是 eor'   和eor^eor'

>>  右移   a >> 1 相当于a/2

<<  左移  a  <<  1 相当于a*2;

a*2 + 1 == (a<<2) | 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值