1.位运算就是直接对整数在内存中的二进制位进行操作,针对与int类型进行操作
Java中常用的位运算符有以下7种:
& | | | ^ | ~ | << | >> | >>> |
按位与 | 按位或 | 按位异或 | 取反 | 左移 | 带符号右移 | 无符号右移 |
2.运算方法
按位与运算(双目运算符):
对应的两个二进制位均为1时取1,否则取0
二进制数 | |
3 | 0011 |
5 | 0101 |
3&5 | 0001 |
结果:3&5=1 ( 0011 & 0101 = 0001 )
按位或运算(双目运算符):
对应的两个二进制位均为0时取0,否则取1
二进制数 | |
3 | 0011 |
5 | 0101 |
3|5 | 0111 |
结果:3|5=7 ( 0011 | 0101 = 0111 )
按位异或运算(双目运算符):
对应的两个二进制位相同时取0,相异时取1
二进制数 | |
3 | 0011 |
5 | 0101 |
3^5 | 0110 |
结果:3^5=6 ( 0011 ^ 0101 = 0110 )
取反运算(单目运算符):
对应的每个二进制位取反,0变1,1变0
二进制数 | |
3 | 0011 |
~3 | 1100 |
左移运算(双目运算符):
左移n位就是乘以2的n次方
例:0001<<3 :3是左移的位数
即: 0001 ——>1000 左移3位
带符号右移运算(双目运算符):
右移n位就是除以2的n次方
例:0100>>2 :2是右移的位数
即: 0100——>0001 右移2位
注:如果是正数,二进制串右移的时候用0来填充左边的空位;
如果是负数,右移的时候用1来填充左边的空位
例:3>>2
右移前:0100
右移后:00 0100
-3>>2
右移前:1100
右移后:11 1100
无符号右移运算(双目运算符):
无符号右移在二进制串移动之后,空位由0来补充,与符号位是0是1毫无关系
例:3>>2
右移前:0100
右移后:00 0100
-3>>2
右移前:1100
右移后:00 1100
3.运算符的优先级
优先级 | 运算符 | 结合性 |
1 | ()【】 | 由左至右 |
2 | !、+(正号)、-(负号)、++、 --(递增与递减运算符)、~(位逻辑运算符) | 由右至左 |
3 | *、/、%(算术运算符) | 由左至右 |
4 | +、-(算术运算符) | 由左至右 |
5 | <<、>>(左位移、右位移运算符) | 由左至右 |
6 | >、>=、<、<= (关系运算符) | 由左至右 |
7 | ==、!= (关系运算符) | 由左至右 |
8 | &(位运算符AND)(位逻辑运算符) | 由左至右 |
9 | ^(位运算符XOR)(位逻辑运算符) | 由左至右 |
10 | |(位运算符OR)(位逻辑运算符) | 由左至右 |
11 | &&(逻辑运算符) | 由左至右 |
12 | ||(逻辑运算符) | 由左至右 |
13 | ?:(条件) | 由右至左 |
14 | =(赋值) | 由右至左 |
4.应用
举例:实现一个算法,确定一个字符串 s
的所有字符是否全都不同。如:
示例一 输入:s = "abcad"
输出: false 示例二 输入:s = "abc"
输出: true
分析:从a到z有26个字符,int类型有32位,使用一个int类型的变量(下文用k表示)来代替长度为26的bool数组。假设这个变量占26个bit(在多数语言中,这个值一般不止26),那么我们可以把它看成000...00(26个0),这26个bit对应着26个字符。
int k = 0;
比如,字符c,检查对应下标的bit值即可判断是否重复,首先计算出字符'c'离'a'这个字符的距离,即我们要位移的距离,用m表示,
int m=s.charAt(i)-'a';
那么使用左移运算符1 << m则可以得到对应下标为1,其余下标为0的数,得到的数为000...00100。
1<<m //1左移m位
完整代码:
public class test {
public static void main(String [] args){
String str = "abc";
test a = new test();
a.isUnique(str);
System.out.println(a.isUnique(str));
}
/*位运算*/
public boolean isUnique(String s){
int k=0;
for(int i=0;i<s.length();i++){
int m=s.charAt(i)-'a';
if((k&(1<<m))!=0){ //判断k的第m位是否为0
return false;
}
else{
k |= (1<<m); //将k的第m位赋值为1
}
}
return true;
}
}
输出结果: