之前学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);
}
}