Java中的异或非

当一个数组只有一个数出现奇数次,其他数都出现偶数次,如何找出这个数?

public static void main(String[] args) {
        int []nums = {1,1,1,2,2,7,7,7,9,9,4,4,5,5};
        int eor = 0;
        for(int i:nums){
             eor = eor^i ;
        }
        System.out.println(eor);
}

0^a = a ---- a^a = 0 异或也满足交换律和结合律

a= a^b
b=b^a
a = a^b
当a,b两个数在内存中不是同一个位置时,交换a,b的值

当一个数组有两个数出现奇数次,其他都是出现偶数次时,如何找出这两个数

public static void main(String[] args) {
       int []nums = {1,1,1,2,2,7,7,7,9,9,4,4,5,5};
       int eor = 0;
       for(int i:nums){
            eor = eor^i ;
       }
       int right = eor & (~eor+1); //提取最右侧的1
       int only = 0;
       for(int i : nums){
           if((i & right) ==0)
               only = only ^ i;
       }
       System.out.println(only +" "+(eor^only));
   }

right = eor & (~eor+1) 这是最常用的 提取一位数二进制里的第一个1

因为 eor = 1111 0101
~eor = 0000 1010
~eor+1 = 0000 1011
eor &(~eor+1) = 0000 0001 提取出了eor 二进制最右侧的1

第一次异或时 eor = x ^ y ---- x和y 代表 数组中的两个出现奇数次的数
eor不为0 说明这两个数的二进制位中,最少有一位不为0 如果都为0,eor=0
代码中的right变量就是保存eor中的第一位1。(我们假设第二位是1),原数组中的所有数现在分为:第二位为1的数和第二位不为1的数。
x和y中必定是一个数第二位为1,一个数第二位不为1,因为根据异或原则,相同为0不同为1,既然x和y异或后有1,那么肯定他们两个数第二位不同。
用right变量(保存着第一位1)和数组中的数进行与运算,如果等于0(或者不等于0),就用only变量进行异或操作,因为只有两个数出现奇数次 而且这两个数第二位不相同(开始时我们假设第二位不同),那么最后only必然等于其中一个数
输出only 和 eor^only即可得到两个数


~ 非操作 即把一个数二进制都取反

4 = 0000 0100
~4 = 1111 1011
此时,因为计算机中都是用补码表示数字的 那么~4的补码就是 1000 0101 = -5

原码反码补码的转换 (最高位是符号位)

正数的原码 反码 补码 都相同
负数的反码=除符号位以外 其余位取反
负数的补码=反码+1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值