位运算

Posted g0rez

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算相关的知识,希望对你有一定的参考价值。

&(与)、| (或)、^(异或)、~ (非/取反)

判断奇偶数 x&1=1为奇数 =0为偶数 原因:奇数最后一位是1,&1后为1,偶数最后一位为0,&1后为0

1.将整数的二进制奇偶位互换

package 蓝桥杯算法;

import java.util.Scanner;
/**
 * 例如 1001 变为0110
 * 1001&1010=1000保留偶数位
 * 1001&0101=0001保留奇数位
 * 偶数位右移  >> 0100
 * 奇数位左移  >> 0010
 * 两者异或  0100^0010=0110
 * 可得结果
 * */
public class 将整数的二进制奇偶位互换 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        System.out.println(Integer.toBinaryString(N));
        int ou=N&0xaaaaaaaa;//和1010 1010 ...做与运算得到偶位
        int ji=N&0x55555555;//和0101 0101 ...做与运算得到奇位
        N=(ou>>1)^(ji<<1);
        System.out.println(Integer.toBinaryString(N));
    }
}

 

2.找出唯一成对的数

package 蓝桥杯算法;

import java.util.Arrays;
import java.util.Random;
/**
 * 由于A^A=0
 * A^0=A
 * 所以在数组中的所有数进行^可以消去相同的数 结果为奇数个数的那个数据
 * 例如: 1^1^2^2^3=3
 * 所以找唯一成对的数可以写两个循环
 * 第一个循环对在该范围的数据进行^
 * 第二个循环利用第一个循环的结果对该数组中的数据进行^
 * 得到的结果就是唯一成对的数  因为这样成对的数据异或了三次
 */

public class 找出唯一成对的数 {
    public static void main(String[] args) {
        int N=100;
        int[] arr=new int[N];
        for (int i = 0; i <arr.length-1 ; i++) {
            arr[i]=i+1;
        }
        arr[N-1]=new Random().nextInt(N-1)+1;
        int index=new Random().nextInt(N);
        int t;
        t=arr[N-1];
        arr[N-1]=arr[index];
        arr[index]=t;
        System.out.println(Arrays.toString(arr));
        int x=0;
        for (int i = 0; i <N-1 ; i++) {
            x=x^(i+1);
        }
        for (int i = 0; i <N ; i++) {
            x^=arr[i];
        }
//        x^x=0,出现两次的消去,剩下出现三次的
        System.out.println(x);
//        辅助空间方法
        int[] h=new int[N];
        for (int i = 0; i <N ; i++) {
            h[arr[i]]++;
        }
        for (int i = 0; i < N; i++) {
            if(h[i]==2){
                System.out.println(i);
            }
        }
    }
}

3.二进制中1的个数

package 蓝桥杯算法;

import java.util.Scanner;

public class 二进制中1的个数 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        System.out.println(Integer.toString(N, 2));
        int count = 0;
/**
 * 第一种解法
 * int类型是32位  利用移位操作
 * N与 1 10 100 1000 ....做&运算 的结果如果等于1<<i位后的结果则计数
 * 就比如:N假设为1001
 * 10001&00001 == 00001 相等 则计数 说明该位置为1
 * ...........
 * 10001&10000 == 10000 说明该位置为1
 * 相等的次数即为1的个数
 *
 * 当然这种是1进行左移操作, 也可以利用N来进行右移与1进行&操作进行判断1的个数
 * */
        for (int i = 0; i < 32; i++) {
            if ((N & (1 << i)) == 1 << i) {
                count++;
            }
        }
        System.out.println(count);
/**
 * 另一种解法
 * 这种解法的思想就是,把N中的每个一干掉,最后当N为0的时候 干掉1的次数也就是N中1的个数
 * 例如  1100
 * 1100-1=1001然后与1100做&运算 低位的1就被干掉了 N变为1000
 * 1000-1=0111 然后与1000做&运算 N变为0 由此可见1的个数为2
 * 干掉1的次数也就是1的个数
 * */
        count = 0;
        while (N != 0) {
                N = (N - 1) & N;
                count++;
        }
        System.out.println(count);
    }
}

4.一个整数是不是2的整数次方

package 蓝桥杯算法;

import java.util.Scanner;
//2的整数次方 也就是说对应二进制位上只有一个是1 其他全为0 即1的个数为1
public class 一个整数是不是2的整数次方 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        if((N&(N-1))==0) System.out.println("YES");
        else System.out.println("NO");
    }
}

以上是关于位运算的主要内容,如果未能解决你的问题,请参考以下文章

编程思想:巧用位运算重构代码

基础位运算基本原理和应用

位运算相关

优雅代码05-从hashMap源码介绍位运算符

c语言位运算问题?

为啥 JSHint 反对位运算符?我应该如何表达这个代码?