位运算(异或+与)的妙用
@TOC前言真正在公司中的实践:NoSQL + RDBMS 一起使用才是最强的,阿里巴巴的架构演进!技术没有高低之分,就看你如何去使用!(提升内功,思维的提高!)云计算的长征之路:阿里云的这群疯子1. 异或 ^无进位相加,满足交换律 结合律0^N == N N^N == 0例子1. 如何不用额外变量交换两个数int a = 16;int b = 6
·
位运算 异或+与 的妙用
前言
真正在公司中的实践:NoSQL + RDBMS 一起使用才是最强的,阿里巴巴的架构演进! 技术没有高低之分,就看你如何去使用!(提升内功,思维的提高!) 云计算的长征之路:阿里云的这群疯子1. 异或 ^
无进位相加,满足交换律 结合律
0^N == N N^N == 0
1.1 如何不用额外变量交换两个数
int a = 16;
int b = 61;
System.out.println("a交换前的值为:"+a);
System.out.println("b交换前的值为:"+b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("a交换后的值为:"+a);
System.out.println("b交换后的值为:"+b);
1.2 —个数组中有一种数出现了奇数次,其他数都出现了偶数次,找到并打印这种数
public static void printOddTimesNum1(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
System.out.println(eor);
}
2. 与 ^
两个位都为1时,结果才为1
2.1 把一个int类型的数,提取出最右侧的1来
int eor = 10;
// ~eor 取反
int rightOne = eor & (~eor+1); //rightOne = 2
// 10 -> 1010
//~10 -> 0101
//~10+1-> 0110
//10 & (~10+1) = 0010=2
3. 异或&与^结合的奇妙例子
3.1 统计二进制1的个数
public static int bit1counts(int N) {
int count = 0;
// 011011010000
// 000000010000 1
// 011011000000
//
while(N != 0) {
int rightOne = N & ((~N) + 1);
count++;
N ^= rightOne;
// N -= rightOne
}
return count;
}
3.2 —个数组中有两种数出现了奇数次,其他数都出现了偶数次,找到并打印这两种数
// arr中,有两种数,出现奇数次。假设两数为a与b
public static void printOddTimesNum2(int[] arr) {
int eor = 0;
for (int i = 0; i < arr.length; i++) {
eor ^= arr[i];
}
// a 和 b是两种数
// eor != 0 因为a^b!=0
// eor最右侧的1,提取出来
// eor : 00110010110111000
// rightOne :00000000000001000
int rightOne = eor & (-eor+1); // 提取出最右的1
//此时,两奇数a,b与其对应的偶数,已根据rightOne分离开来
int onlyOne = 0;
for (int i = 0 ; i < arr.length;i++) {
// arr[1] = 111100011110000
// rightOne= 000000000010000
if ((arr[i] & rightOne) == 0) {
onlyOne ^= arr[i];
}
}
System.out.println("两种出现奇数次的数分别为:"+onlyOne + " " + (eor ^ onlyOne));
}
更多推荐
已为社区贡献13条内容
所有评论(0)