用二进制的一位表示集合对应某一元素的选取状态,1 表示选取,0 表示未选取;
----------------------------------------------------------------------------------------------------------
先介绍位运算:位运算是对二进制的每一位进行计算,所以每一位只有 0或 1两种可能
三种常用的位运算符:与&
、或|
、异或^;
- 与运算:两者都为 1时,结果即为1,否则为0。--有0出0
- 或运算:两者都为 00时,结果即为0,否则为1。--有1出1
- 异或运算:是两者同为 0 或1 时,结果即为0,否则为1。相同出1 ,相异出0;
位运算符中有两种操作,左移<<
和右移>>
。
对于A << B
,表示把A
转化为二进制后向左移动B
位(在末尾添加B
个0
)。
对于A >> B
,表示把A
转化为二进制后向右移动B
位(删除末尾的B
位)。
如2<<2 就是二进制的10左移2位:二进制的1000 转为10进制为8;
这里也看的出来2<<2 就是 2*(2的二次方);2<<3就是2*(2的三次方);
面试题:用最有效率的方法算出2乘以8等於几?
2 << 3,
因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2 << 3
题目:
对于一个数的二进制表示,交换其高低位顺序。比如,对于整数
123523532123523532
123523532 的二进制表示:
00000111 01011100 11010001 11001100
交换后的结果为
11001100 11010001 01011100 00000111
import java.util.Scanner;
class Main {
public static void print(long x) {
for (int i = 31; i >= 0; --i) {
if ((x&(1L<<i)) > 0) System.out.print("1");
else System.out.print("0");
if (i % 8 == 0) {
if (i > 0) System.out.print(" ");
else System.out.print("\n");
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
long x = scanner.nextLong();
long mask = (1L<<32)-1;//1左移得到10000..... 然后-1 得到1111.......
print(x);
x=((x<<24)&mask)+((x>>24)&mask)+((x<<8)&0x00FF0000)+((x>>8)&0X0000FF00);//可以用&上1或者0来得到或者删除相应位的数字;
print(x);
}
}
----------------------------------------------------------------------------------------------------------
位运算介绍完了 看如何用二进制枚举:
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为1,遇花记为0。
public class 李白打酒二进制 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int ans = 0;
for (int i = 0; i < (1<<14); ++i) {
int tot_1 = 0;
int tot_0 = 0;
int num = 2;
for (int j = 0; j < 14; ++j) {//从0开始,到13,一共14位;查看每一位是0还是1
//j为0时,i&1-->查看的第一位;j为1时i&10-->查看第二位...以此类推
if ((i&(1<<j))==1) { // 这里判断二进制 i 从右数第 j + 1 位是否为 1
tot_1++;
num = num * 2;
} else {
tot_0++;
num = num - 1;
}
}
if (tot_1 == 5 && tot_0 == 9 && num == 1) {
++ans; // 记录合法方案数
}
}
}
}