zoukankan      html  css  js  c++  java
  • 算法:异或运算^

    package club.interview.algorithm.eor;
    
    import java.util.Arrays;
    
    /**
     * 异或运算 == 无进位相加
     * 1. 找到整数二进制最后一个1的下标位置 {@link EorT#findIndexOne(int)}  }
     * 2. 统计整数二进制中1的个数 {@link EorT#countOne(int)}
     * 3. 找到数组中出现奇数次的1个数 {@link EorT#findNumOdd(int[])}
     * 4. 找到数组中出现奇数次的2个数 {@link EorT#findNumOdd2(int[])}
     * <p>
     * 知识点扫盲
     * 1. 异或运算特点
     * *  1.1 N = N ^ 0
     * *  1.2 0 = N ^ N
     * *  1.3 满足交换律和结合律
     * 2. 打印整数的二进制 {@link Integer#toBinaryString(int)}
     * 3. 对数求解 {@link Math#log(double)}
     *
     * @author QuCheng on 2020/6/13.
     */
    public class EorT {
    
        /**
         * 1.找到整数二进制最后一个1的下标位置
         */
        private int findIndexOne(int num) {
            if (num == 0) return -1;
            return log2(num & (~num + 1));
        }
    
        /**
         * 2. 统计整数二进制中1的个数
         */
        private int countOne(int num) {
            int count = 0;
            while (num != 0) {
                count++;
                int rightOne = num & (~num + 1);
                num ^= rightOne;
            }
            return count;
        }
    
        /**
         * 3. 找到数组中出现奇数次的1个数
         * ** 数组中有且只有一个数出现过奇数次,找到该数字
         */
        private int findNumOdd(int[] num) {
            int eor = 0;
            for (int i : num) eor ^= i;
            return eor;
        }
    
        /**
         * 4. 找到数组中出现奇数次的2个数
         * ** 数组中有且只有2个数出现过奇数次,找到该数字
         */
        private int[] findNumOdd2(int[] num) {
            int eor = 0;
            // eor为a^b
            for (int i : num) eor ^= i;
    
            // eor1 为 a
            int rightAeorB = eor & (~eor + 1);
            int eor1 = 0;
            // 根据rightAeorB二进制中的1将A和B区分开
            for (int i : num)
                if ((i & rightAeorB) == rightAeorB)
                    eor1 ^= i;
    
            // eor 为 b
            eor ^= eor1;
            return new int[]{eor, eor1};
        }
    
    
        public static void main(String[] args) {
            EorT e = new EorT();
            System.out.println("二进制打印 : " + Integer.toBinaryString(-2));
            int[] findIndexOne = {-1, 0, 5, 8};
            for (int i : findIndexOne) System.out.println("二进制中最后一个1的位置 " + i + " : " + e.findIndexOne(i));
            System.out.println("------------------");
    
            for (int i : findIndexOne) System.out.println("二进制中1出现次数 " + i + " : " + e.countOne(i));
            System.out.println("------------------");
    
            int[] findNumOdd = {12, 12, 5, 3, 6, 12, 3, 5, 6};
            System.out.println("出现奇数次的1个数 " + Arrays.toString(findNumOdd) + " : " + e.findNumOdd(findNumOdd));
    
            System.out.println("------------------");
            int[] ints = {12, 12, 5, 3, 6, 12, 3, 5, 6, 3};
            System.out.println("出现奇数次的2个数 " + Arrays.toString(ints) + " : " + Arrays.toString(e.findNumOdd2(ints)));
        }
    
    
        /**
         * 工具方法:对数求解
         */
        private int log2(int num) {
            return (int) (Math.log(num) / Math.log(2.0));
        }
    }
    

      

  • 相关阅读:
    知识小罐头05(tomcat8请求源码分析 上)
    知识小罐头04(idea+maven+部署war包到tomcat 下)
    知识小罐头03(idea+maven+部署war包到tomcat 上)
    带着新人学springboot的应用13(springboot+热部署)
    带着新人学springboot的应用12(springboot+Dubbo+Zookeeper 下)
    带着新人学springboot的应用11(springboot+Dubbo+Zookeeper 上)
    带着新人学springboot的应用10(springboot+定时任务+发邮件)
    带着新人学springboot的应用09(springboot+异步任务)
    带着新人学springboot的应用08(springboot+jpa的整合)
    windows最简单的局部截图工具
  • 原文地址:https://www.cnblogs.com/nightOfStreet/p/13113415.html
Copyright © 2011-2022 走看看