java 位运算

之前学java感觉位运算都用不到,因此当时学的就很不认真,今天做算法题看到一个题,用位运算感觉很方便,以后做算法题也可以多个思路,因此今天总结一下位运算的相关操作:

左移

将5左移2位
System.out.println(5<<2);//运行结果是20
java中int 默认4字节 32 位
0000 0000 0000 0000 0000 0000 0000 0101 左移两个字节得
0000 0000 0000 0000 0000 0000 0001 0100 换成10进制为20

右移

将5右移2位
System.out.println(5>>2);//运行结果是1
右移高位补0,结果为1

无符号右移

Java中int类型占32位,可以表示一个正数,也可以表示一个负数。正数换算成二进制后的最高位为0,负数的二进制最高为为1
另外还要注意,计算机中是采用补码的方式存取的二进制。
-5的二进制表示
原码10000101;
反码11111010;
补码11111011
例如 -5换算成二进制后为:
1111 1111 1111 1111 1111 1111 1111 1011
我们分别对5进行右移3位、 -5进行右移3位和无符号右移3位:
System.out.println(5>>3);//结果是0 高位补的0
System.out.println(-5>>3);//结果是-1 高位补的1
System.out.println(-5>>>3);//结果是536870911 高位补的0

正数右移,高位用0补,负数右移,高位用1补,当负数使用无符号右移时,用0进行部位(自然而然的,就由负数变成了正数了)
笔者在这里说的是右移,高位补位的情况。正数或者负数左移,低位都是用0补

位与(&)

System.out.println(5 & 3);//结果为1
System.out.println(5 & 5);//结果为5

5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

1转换为二进制:0000 0000 0000 0000 0000 0000 0000 0001

位或(|)

System.out.println(5 | 3);//结果为7
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

7转换为二进制:0000 0000 0000 0000 0000 0000 0000 0111

位异或(^)

System.out.println(5 ^ 3);//结果为6
System.out.println(5 ^ 5);//结果为0
System.out.println(5 ^ 3^5);//结果为3
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101

3转换为二进制:0000 0000 0000 0000 0000 0000 0000 0011

6转换为二进制:0000 0000 0000 0000 0000 0000 0000 0110

位非(~)

System.out.println(~5);//结果为-6
System.out.println(~-5);//结果为4
5转换为二进制:0000 0000 0000 0000 0000 0000 0000 0101
-6转换为二进制:1111 1111 1111 1111 1111 1111 1111 1010

  • 注意这是一个规律:~n 结果为 -n+1 ~-n 结果为 n-1

相关衍生

&= 按位与赋值
|= 按位或赋值
^= 按位非赋值
“>>= 右移赋值”
“>>>= 无符号右移赋值”
<<= 赋值左移
\
和 += 一个概念而已。

算法实例

  • 题目:
    一个整型数组中有一个元素只出现一次,其它元素都出现两次。求出只出现一次的元素。
    要求:
    线性时间复杂度,不能使用额外空间。
    聪明的你能搞定吗?
    格式:
    第一行输入数字n,代表有n个数,根据题意,很明显n是奇数,
    第二行输入数组A[i], i从0~n-1.
    最后输出单独的数字。

样例输入
7
1 3 2 0 3 2 1

样例输出
0

  • 代码


import java.util.*;
public class Main{
public static void main(String args[])
{
Scanner in =new Scanner(System.in);
int num=in.nextInt();
int []a=new int[num];
int result=0;
for(int i=0;i<num;i++) {
a[i]=in.nextInt();
result^=a[i];
}
System.out.println(result);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值