异或运算 - ^
作者:互联网
^ 运算符(异或)
-
两个值不同为1 相同为0
-
基础理论
-
首先有 0 ^ N = N , N ^ N = 0
-
符合交换律,以及结合律
-
a ^ b = b ^ a
-
(a ^ b) ^ c = a ^ (b ^ c)
-
-
异或运算的结构与运算的顺序无关
-
-
例子
-
假设有二进制数 0101(5) 5 ^ 5: 0101 0101 =>0000 5 ^ 0: 0101 0000 =>0101
-
-
代码案例
-
使用异或运算的冒泡排序
-
function swap(arr: Array<number>, i: number, j: number) { // arr[i] 和 arr[j] 做了交换 // 假设 arr[i] 为甲 arr[j] 为乙 // 甲 = 甲 ^ 乙 此时的值 甲 = 甲 ^ 乙 | 乙 = 乙 // 乙 = 甲 ^ 乙 此时的值 甲 = 甲 ^ 乙 | 乙 = 甲 ^ 乙 ^ 乙 = 甲 // 甲 = 甲 ^ 乙 此时的值 甲 = 甲 ^ 乙 ^ 甲 ^ 乙 ^ 乙 = 乙 // // arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j]; arr[i] = arr[i] ^ arr[j]; } function bubbleSort(arr: Array<number>) { if (arr == null || arr.length < 2) { return; } for (let e = arr.length - 1; e > 0; e--) { for (let i = 0; i < e; i++) { if (arr[i] > arr[i + 1]) { swap(arr, i, i + 1); } } } return arr; } let arr = [1, 3, 2, 1, 2, 1, 33, 445, 2, 8, 766, 76, 334]; console.log(bubbleSort(arr));
-
-
使用的前提
-
再异或的两个数中不能相同(数值,以及物理地址相同),不然会归零
-
-
算法真题
-
请找出一列数中出现奇数次的数
// 思路 只要一直异或算法下去,就能找到那个为奇数个的数 // 因为偶数个的数进行异或运算的时候 = 0,奇数个的是本身 function printOddTimesNums(arr: Array<number>) { let eor = 0; for (let cur in arr) { eor ^= arr[cur]; } return eor; } let arr = [1, 1, 2, 2, 2, 3, 3, 4, 4]; console.log(printOddTimesNums(arr));
-
进阶版—找到一列数列中的两个出现奇数次的数
function printOddTimesNums2(arr: Array<number>) { let eor = 0; for (let cur in arr) { eor ^= arr[cur]; } // 首先进行异或运算,假设有奇数个数的值为a / b // 现在进行异或运算之后 eor 就等于 a ^ b // 现在要做的就是找到 a 或者 b 的值 // 通过 eor & (~eor + 1); 的方式找到eor 右边的第一个 1(rightOne)(在a或者b中必定有一个数有这一数) // 假设 eor: 0101 // ~eor = 1010 ( ~ 是翻转的意思) // ~eor+1 = 1011 // eor & (~eor + 1) = 0101 // 1011 = 0001 let rightOne = eor & (~eor + 1); let onlyOne = 0; for (let cur in arr) { if ((arr[cur] & rightOne) == 0) { // 增加判断条件 首先异或运算找到 a ^ b 再判断a或者b中哪个数有这个值 可以找到 a 或者 b 我们假设是a onlyOne ^= arr[cur]; } } // 最后打印 a 和 a^b^a =b console.log(onlyOne + " " + (eor ^ onlyOne)); } let arr = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4]; printOddTimesNums2(arr);
-
标签:arr,运算,0101,eor,异或,let,cur 来源: https://blog.csdn.net/mjjhen/article/details/120165286