位操作应用与总结

基本的位操作符有与、或、异或、取反、左移、右移这6种,它们的运算规则如下所示:

位操作符

符号描述运算规则
&两个位都为1时,结果才为1
|两个位都为0时,结果才为0
^异或两个位相同为0,相异为1
~取反0变1,1变0
<<左移各二进制位全部左移 若干位,高位丢弃,低位补0
>>算术右移各二进制位全部右移 若干位,高位补符号位(算术右移)
>>>逻辑右移各二进制位全部右移 若干位, 高位补0

1. 异或(重点

1.1 性质

1、交换律
2、结合律(即(a^b)^c == a^(b^c))
3、对于任何数x,都有x ^ x = 0,x ^ 0 = x
4、自反性 a ^ b ^ b = a ^ 0 = a


即对给定的数A,用同样的运算因子(B)作两次异或运算后仍得到A本身。这是一个神奇的性质,利用这个性质,可以获得许多有趣的应用

应用

1. 判断奇偶数

在计算机做运算的时候会将所有的东西转化为二进制数,要判断奇偶数,只需要判断该数化为二进制的形式,末尾是0还是1

if(i & 1 == 0){
    System.out.println(i)//偶数
}else{
    System.out.println(i)//奇数
}


我们利用的与的特点:两个1为1!

2. 交换两个数

不用临时变量交换两个数

int a = 10, b = 15;
a ^= b; 
b ^= a;
a ^= b;

System.out.println("a  = " + a);
System.out.println("b = " + b);

这里解释一下:
A=A ^ B (a ^ b)
B=B ^ A (b ^ a ^ b = a)
A=A ^ B (a ^ b ^ a = b)

3. 二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

public static int numberOfOne(int n) {  
        // 记录数字中1的位数  
        int result = 0;  
        // 数字的二进制表示中有多少个1就进行多少次操作  
        while (n != 0) {  
            result++;  
            // 从最右边的1开始,每一次操作都使n的最右的一个1变成了0,  
            // 即使是符号位也会进行操作。  
            n = (n - 1) & n;  
        }  
        // 返回求得的结果  
        return result;  
    }

总结

1. x & (x - 1) 用于消去x最后一位的1

这里写图片描述

2. 判断重复数出现

利用异或运算的自反性
a ^ b ^ b = a ^ 0 = a

3. 使用二进制进行子集枚举

练习的题

public int missingNumber(int[] nums) { //binary search
    Arrays.sort(nums);
    int left = 0, right = nums.length, mid= (left + right)/2;
    while(left<right){
        mid = (left + right)/2;
        if(nums[mid]>mid) right = mid;
        else left = mid+1;
    }
    return left;
}
  1. 给定一个包含n个不同数字的数组0, 1, 2, …, n,找到数组中缺少的数字。

例1

输入: [3,0,1]
输出: 2
例2

输入: [9,6,4,2,3,5,7,0,1]
输出: 8

https://www.cnblogs.com/jfwu/p/5561567.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值