【算法&数据结构体系篇class02】:异或运算技巧

package train;

public class EvenTimesOddTimes {
    // arr中,只有一种数,出现奇数次   运用异或运算 自身偶数个异或值为0的特点来处理
    public static void printOddTimesNum1(int[] arr) {
        int eor = 0;
        for(int i = 0; i<arr.length;i++){
            eor ^= arr[i];
        }
        System.out.println(eor);
    }

    // arr中,有两种数a,b,出现奇数次  异或后结果就是a^b的结果 再利用这个位运算技巧来拆分两个数
    public static void printOddTimesNum2(int[] arr) {
        int eor = 0;
        for(int i= 0;i<arr.length;i++){
            eor ^= arr[i];
        }
        //a^b接着就是把异或的值,两数不一样就代表肯定存在某一位为1 异或就是不同为1,表示这一位一个是1 另一个是0 取出最右侧的1,然后再将这个值
        //与每个值进行 与运算, 这样与完 为1的就是a或者b了
        //取出最右侧位1 其余位为0的一个值
        int rightOne = eor & (-eor);
        //接收一个数a
        int a = 0;
        for(int i = 0;i<arr.length;i++){
            if((arr[i] & rightOne) != 0){
                a ^= arr[i];
            }
        }
        //另外一个数b 就可以用前面eor的值异或a,因为eor= a^b  再^b就等于b
        int b = eor ^ a;
        System.out.println("奇数为"+ a+"---"+b);
    }

    // 输入一定能够保证,数组中所有的数都出现了M次,只有一种数出现了K次
    // 1 <= K < M
    // 返回这种数
    public static int km(int[] arr, int k, int m) {
        //定义一个整形数组来存放全部数组元素二进制,将每一个进制位为1的进行累加
        int[] temp = new int[32];
        for(int num: arr){
            for(int i = 0;i<32;i++){
                temp[i] += ((num>>i)&1);
            }
        }
        //接收k个元素的结果值
        int ans = 0;
        for(int i = 0; i< 32;i++){
            //其余数都是m个,如果元素出现m次,当前二进制位是1,那么求模肯定是等于0,
            // 不为0,说明出现k次的元素当前二进制位为1
            temp[i] %= m;
            if(temp[i] != 0){
                //不为0 说明该位1是出现k次的元素,则用或运算,把1加到ans结果值上
                ans |= 1<<i;
            }
        }
        return ans;
    }

    //判断一个数的二进制中有多少个1
    public static int bit1counts(int N) {
        int count = 0;
        while(N != 0){
            //取出一个二进制,是最右侧为1的二进位
            int rightOne = N & (-N);
            //N 异或 最右侧为1的而二进制数, 就相当于减去最右侧1 剩余的值
            N ^= rightOne;
            //计数器+1
            count++;
        }
        return count;
    }


    public static void main(String[] args) {
        int a = 5;
        int b = 7;

        a = a ^ b;
        b = a ^ b;
        a = a ^ b;

        System.out.println(a);
        System.out.println(b);

        int[] arr1 = { 3, 3, 2, 3, 1, 1, 1, 3, 1, 1, 1 };
        printOddTimesNum1(arr1);

        int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
        printOddTimesNum2(arr2);

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值