• 位运算的一些经典题目


    java中提供的基础位运算符有 与(&),或(|),非(~),异或(^),左移<<,右移(>>)和无符号右移(>>>)
    除了位非(~)是一元操作符外,其它的都是二元操作符
    异或运算满足 交换律 和 结合律,①0 ^ N == N ② N ^ N == 0
    为什么右移有“有无”符号之别,而左移却没有?(留个尾巴,后续补充)

    不用第三个变量交换两个数

     /**
         * 利用位的异或运算进行交换操作
         */
        public static void swap(){
            int a = 23;
            int b = 45;
    
            a = a ^ b;
            b = a ^ b;
            a = a ^ b;
    
            System.out.println("a:"+a+"====b:"+b);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    查找数组中出现奇数次的一种数

    public static void findOneAppearOdd(){
            int[] arr = {2,3,4,3,4,2,2,7,2,5,6,6,5};
    
            int result = 0;
            //将数组中所有的数都进行异或,那些出现偶数次的数字就抵消掉了
            for(int i=0; i<arr.length; i++){
                result ^= arr[i];
            }
            System.out.println("数组中出现奇数次的一种数为:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查找数组中出现奇数次的两种数

     public static void findTwoAppearOdd(){
            int[] arr = {2,3,4,3,4,2,2,7,2,5,6,6,5,8};
    
            int result = 0;
            //将数组中所有的数都进行异或,那些出现偶数次的数字就抵消掉了
            for(int i=0; i<arr.length; i++){
                result ^= arr[i];
            }
    
            //查找result最右边为1的数字
            int rightOne = result & (~result + 1);
            int oneTarget = 0;
            for(int i=0; i<arr.length; i++){
                if((rightOne & arr[i]) > 0){
                    oneTarget ^=  arr[i];
                }
            }
    
            int anotherTarget = result ^ oneTarget;
            System.out.println("查找结果为:"+oneTarget +"======="+ anotherTarget);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    判断一个数是否为2的整数次幂

    /**
         * 校验一个数是否为2的整数次幂
         * @param a
         * @return
         */
        private static boolean check2Pow(int a) {
            //去掉最右侧的1以后,理论上该变为0的
            return (a & (a-1)) == 0;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    统计一个数转换为2进制后1的个数

    /**
         * 位操作统计二进制中 1 的个数
         * @param m
         * @return
         */
        private static int getNumOfOne(int m){
            int count = 0;
            while(m > 0){
                //该操作会卸下m最右侧的1
                m = m & (m-1);
                count++;
            }
            return count;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用位域进行多标记(状态)管理

    public class BitMapUtil {
    
    
        /**
         * 加上某一个位上的值
         * @param value
         * @param bitValue
         * @return
         */
        public static int addFlag(int value, int bitValue){
            if(checkFlag(value, bitValue)){
                return value;
            }
            return value | bitValue;
        }
    
        /**
         * 移除某一位上的值
         * @param value
         * @param bitValue
         * @return
         */
        public static int removeFlag(int value, int bitValue){
            if(!checkFlag(value, bitValue)){
                return value;
            }
            return value ^ bitValue;
        }
    
        /**
         * 校验某一个位上是否有值
         * @param value
         * @param bitValue
         * @return
         */
        public static boolean checkFlag(int value, int bitValue){
            return (value & bitValue) > 0 ;
            //return (value & bitValue) == bitValue ;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    排序算法(1)之插入排序----直接插入排序和希尔排序
    【python爬虫笔记】验证码
    聚苯乙烯/Fe3O4纳米复合材料PS@Fe3O4|硫化锌-四氧化三铁(ZnS/Fe3O40纳米复合物(齐岳)
    css_css3新特性
    大数据必学Java基础(九十六):PreparedStatement完成CURD和批处理
    一站制造项目及Spark核心面试 ,220808,,,
    开放内容处理框架(OCPF),轻松玩转各类数据处理
    进阶面试皆宜!阿里强推Java程序员进阶笔记,差距不止一点点
    Hive的UDF开发之向量化表达式(VectorizedExpressions)
    新手入门MySQL数据库【基础知识】
  • 原文地址:https://blog.csdn.net/wangchenggong1988/article/details/126084397