认识异或运算

异或(eor)是一个数学运算符,它应用于逻辑运算。
异或运算:相同为0,不同为1;可以理解成无进位相加。
异或运算性质:
(1) 0 ^ N = N; N ^ N = 0
(2) 满足交换律、结合律、自反

下面由几个问题入手,深入理解异或运算(^)
一.如何不用额外变量交换两个数

num1 = num1 ^ num2;
num2 = num1 ^ num2;
num1 = num1 ^ num2;

二.一个数组中有一个数出现了奇数次,其他数都出现了偶数次,怎样找到并打印这个数

private static void printOddNum(int[] arr) {
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
        eor ^= arr[i];
    }
    System.out.println("出现奇数次的数为:" + eor);
}

public static void main(String[] args) {
    int[] arr = {1, 3, 2, 2, 3, 1, 2};
    printOddNum(arr);
}

在这里插入图片描述
三.已知一个int类型的数,提取出最右侧的1来(ex:11100 -> 100)

private static void getRightOneNum(int num) {
    System.out.println(num + "转换为二进制:" + Integer.toBinaryString(num));
    int rightOneNum = num & (~num + 1);
    System.out.println(rightOneNum + "转换为二进制:" + Integer.toBinaryString(rightOneNum));
}

public static void main(String[] args) {
    getRightOneNum(28);
}

在这里插入图片描述
解释下num & (~num + 1)

四.已知一个int类型的数,统计其中包含多少个二进制数1

private static void getBit1Count(int num) {
    int count = 0;
    int rightOne;
    while(num != 0) {
        rightOne = num & (~num + 1);
        count++;
        num ^= rightOne;
    }
    System.out.println("包含二进制1的个数为:" + count);
}

public static void main(String[] args) {
    getBit1Count(28);
}

在这里插入图片描述
五.一个数组中有两个数出现了奇数次,其他数都出现了偶数次,怎样找到并打印这两个数

private static void printOddNum2(int[] arr) {
    int eor = 0;
    for (int i = 0; i < arr.length; i++) {
        eor ^= arr[i];
    }
    //已知出现奇数次的两个数为num1、num2  则此时eor = num1 ^ num2
    //eor值不为0 二进制位一定包含1
    int rightOne = eor & (~eor + 1);
    int num1 = 0;
    for (int i = 0; i < arr.length; i++) {
        if ((arr[i] & rightOne) == 0) {
            //出现偶数次的数rightOne位置值为1的数量一定为偶数,值为0的数量也一定是偶数,可以互相抵消
            //因为rightOne值存在,所以num1、num2在rightOne位置的值一定是一个0,一个1
            num1 ^= arr[i];
        }
    }
    System.out.println("出现奇数次的两个数为:" + num1 + "," + (eor ^ num1));
 }

 public static void main(String[] args) {
     int[] arr = {3, 4, 3, 2, 1, 2, 3, 3};
     printOddNum2(arr);
 }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值