ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

异或运算 - ^

2021-09-07 19:33:08  阅读:298  来源: 互联网

标签:arr 运算 0101 eor 异或 let cur


^ 运算符(异或)

  • 两个值不同为1 相同为0

  • 基础理论

    1. 首先有 0 ^ N = N , N ^ N = 0

    2. 符合交换律,以及结合律

      • a ^ b = b ^ a

      • (a ^ b) ^ c = a ^ (b ^ c)

    3. 异或运算的结构与运算的顺序无关

  • 例子

    •  假设有二进制数 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有