位运算简述与例题

位运算符

规则
在处理整形数值时,可以直接对组成整形数值的各个位进行操作。这意味着可以使用屏蔽技术获得整数中的各个位
&(与)、|(或)、^(异或)、~(非/取反)>>和<<
>>和<<运算符将二进制位进行右移或者左移操作
>>>将用0填充高位;>>运算符用符号位填充高位,没有<<< 运算符
对于int型,1<<34与1<<3是相同的,而左边的操作数是long型时需要对右侧操作数模64
与:都为1结果为1,或:有一个为1结果为1,异或:二者不同时结果为1
ab~aa&ba|ba^b
110110
011011
001000
技巧
判断奇偶数,x&1=1奇数,x&1=0偶数
获取二进制位是1还是0 :&
交换两个变量的值
不用判断语句,求整数的绝对值
异或可以理解为不进位加法:1+1=0,0+0=0,1+0=1
技巧
交换律,可任意交换运算因子的位置,结果不变
结合律(即(a^b)^c==a^(b^c))
对于任何数x,都有x^x=0,x^0=x,同自己求异或为0,同0求异或为自己
自反性 A^B^B=A^0=A,连续和同一个因子做异或运算,最终结果为自己

例题

1、找数组中唯一成对的数

题目:
数组a[N],1至N-1这N-1个数存放在a[N]中,其中某个数重复一次。写一个函数,找出被重复的数字。
方法:异或法。
数组a[N]中的N个数异或结果与1至N-1异或的结果再做异或,得到的值即为所求。
实现

class Main {
	public static void main(String[] args) {
        int[] arr=new int[]{1,2,3,4,5,5,6,7,8,9};
        int x=0;
        for(int i=0;i<arr.length;i++){
            x=x^arr[i];
        }
        for(int i=1;i<arr.length;i++){
            x=x^i;
        }
        System.out.println(x);
    }
}

2、找出落单的数

题目:
数组中只有1个数字是出现一次的,其他都出现俩次。
思路:
使用^运算

3、二进制中1的个数

题目:
实现一个函数,输入一个整数,输出该数二进制表示中1的个数
例子:9的二进制表示为1001,有2位是1
代码实现
方法一:
移位1,去探测
1001&1=1;
1001&0010!=0010
1001&0100!=0100
1001&1000=1000;

class Main {
	public static void main(String[] args) {
        int n=9;
        System.out.println(Integer.toString(n,2));
        int count=0;
        for(int i=0;i<32;i++){
            if((n&(1<<i))==(1<<i)){
                count++;
            }
        }
        System.out.println(count);
    }
}

方法二:
1不动,移位x,x高位补零,去探测
1001&1=1;
0100&1=0;
0010&1=0;
0001&1=1;

class Main {
	public static void main(String[] args) {
        int n=9;
        System.out.println(Integer.toString(n,2));
        int count=0;
        for(int i=0;i<32;i++){
            if(((n>>>i)&1)==1){
                count++;
            }
        }
        System.out.println(count);
    }
}

方法三:
消除末位1,统计消除次数
1001-1=1000
1000& 1001=1000;

1000-1=0111
0111&1000=0;
所以:count=2

class Main {
	public static void main(String[] args) {
        int n=9;
        System.out.println(Integer.toString(n,2));
        int count=0;
        while(n!=0){
            n=((n-1)&n);
            count++;
        }
        System.out.println(count);
    }
}

4、是不是2的整数次方

题目;
用一条语句判断是不是2的整数次方
思路:
二进制中只有一个1

if(((n-1)&n)==0)

5、交换整数的奇偶位

思路:
1001&0101=0001
1001&1010=1000
0001左移0010
1000右移0100
0010^0100=0110
代码实现

class Main {
	public static void main(String[] args) {
        int n=9;
        int ji=n&0xaaaaaaaa;
        int ou=n&0x55555555;
        int end=(ou<<1)^(ji>>1);
        System.out.println(end);
    }
}

6、二进制指定位变为0

例如:m=1111
现在想将其变为1001;
可进行操作

i=1,j=2;
mask=((1<<(j-i+1))-1)<<i;
mask=~mask;
m&=mask;

可得1001
其中 i,j分别表示位变化的起始点和终止点

1<<(j-i+1)

这一步后mask=0100
mask-1=0011;
mask<<i=0110;
~mask=1001;
之后mask和m进行与运算得到1001;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值