赞
踩
在位运算之前都需要将运算的数字转为二进制数
1、与(&):两个数都数为1,则该位结果为1,否则为0。
2、非(~):数为1,结果为0;数为0,结果为1。
3、或(|):两个数至少一个1,则运算结果为1;否则结果为0。
4、异或(^):两个数相同则结果为0,不同则为1。
知识点:两个相同的数异或结果为0,任何数与0 的异或结果都是该数本身
1、在不创建变量的情况下交换数组中的两个数
public void swap(int[] arr,int i,int j){
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
注:交换的两个数的内存必须不一样,否则会出问题。数组中,arr[i]必须不等于arr[j],否则会出错,结果会变成0
2、一个数组中有一个数出现了奇数次,其他数都出现了偶数次,怎么找到这个数
public int findOne(int[] arr){
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor = eor ^ arr[i];
}
return eor;
}
知识点为异或运算知识点。
3、提取出一个数(二进制)最右侧的1,如:111 —> 001; 0101110—>0000010
public int getRightOne(int num){
int res = num & ((~num) + 1);
return res;
}
原理:
设num = 7
num | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |
---|---|---|---|---|---|---|---|---|
~num | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
~num + 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
设num = 6
num | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
~num | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
~num + 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 |
就会发现num 和 ~num + 1只有一处都为1,且在最右侧
4、一个数组中有2个数出现了奇数次,其他数都出现了偶数次,怎么找到这两个数
public int[] findTwo(int[] arr){ int eor = 0; for (int i = 0; i < arr.length; i++) { eor = eor ^ arr[i]; } //此时 eor = a ^ b a,b是数组中出现次数为奇数的两个数 //eor != 0 因为a =! b //因此eor必有一位是1 int rightOne = eor & ((~eor) + 1);//提取出最右侧的1 int eor2 = 0; for (int i = 0; i < arr.length; i++) { if((arr[i] & rightOne) != 0){ eor2 = eor2 ^ arr[i]; } } return new int[]{eor2,eor2 ^ eor}; }
5、数出一个数转换成二进制之后包含几个1
public static int bit1counts(int num){
int count = 0;
while (num != 0){
int rightOne = num & ((~num) + 1);
count++;
num = num ^ rightOne;//若是正数,那么可以减;是负数的话减就会出问题
}
return count;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。