算法基础——异或运算符(^)的骚操作


主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, greenwillow, v-green, vue-pro, healer-readable, mk-cute, jzman, geek-black, awesome-green

贡献主题:https://github.com/xitu/juejin-markdown-themes

theme: juejin

highlight:

异或运算符

这是百度百科给出的解释

对于程序算法来说 归零律 1 ^ 1 输出 0 相同的输出0,恒等律 1 ^ 0 输出1

二进制异或运算

|2 |1 |0 |number| |---|---|---|---| |1 |0 |1 |5 | |1 |1 |0 |6 | |1^1=0|0^1=1|1^0=1|5^6=3 |0 |1 |1 |3 |

从这个表格可以看出来 5^6 输出结果是3

从表格看,还是比较清晰的,那么下面看一下十进制和二进制之间的关系

(为啥十进制的5转为2进制是101)

十进制转二进制

使用短除法

javascript转换方法是num.toString(2) 十进制数字转为二进制

可以通过这样的规律写出一个转换工具,方便理解

javascript BinaryToDecimalSystem = function (num) { if (typeof num === "number") { const nrArr = []; // 通过根号计算出需要除几次2 (二进制有几位) const s = Math.ceil(Math.sqrt(num)); let n = num; // 需要计算s次 for (let i = s; i >= 0; i--) { let nr = n % 2 === 0 ? 0 : 1; // 数组向后添加 nrArr.unshift(nr); // 将下一次的计算值赋值给n n = Math.floor(n / 2); } // 至于输出格式这里是数组转字符串 字符串转数字 // 也可以不用数组的unshift,可以直接+=的方式直接输出字符串 return Number(nrArr.join("")); } else { return "error"; } }; const decimal = BinaryToDecimalSystem(65); console.log(decimal); // 1000001

试了几个数字 感觉没什么异样,如果还有其他逻辑,可以一起沟通

可以通过这个方法计算出 5的二进制是101 6的二进制是110

那么二进制异或算法得出结果 011 转数字 0去掉 结果是 11

那么接下来就是将11通过二进制转十进制的方法 得出结果3 javascript提供的方法是 var num = 11 parseInt(num,2) // 3 我们通过自己写的方法来计算一下 方便理解

二进制转十进制采用按权相加法,以1100100为例 转换结果应该是100

同样可以通过这个逻辑写一个方法

``` javascript DecimalSystemToBinary = function (num) { if (typeof num === "number") { const toStr = num.toString(); const len = toStr.length; let count = 0; for (let i = 1; i <= len; i++) { let n = Number(toStr[i - 1]); if (n !== 0) { count += n * 2 ** (len - i); } } return count } else { return 'error' } };

const count = DecimalSystemToBinary(11); console.log(count) // 3 ```

通过这样的互相转换方法 轻易的计算出 5^6=3

例题

在使用异或运算符之前 我们可以通过自己的方法来实现这个功能

javascript var singleNumber = function (nums) { let num = nums.sort((a, b) => { return a - b; }); let n = num[0]; for (let i = 1; i < num.length; i++) { if (n === num[i]) { n = num[i + 1] || num[num.length-1]; i++ } } return n; }; const arr = [4,1,2,1,2]; console.log(singleNumber(arr)); // 4

用这种方法 又要排序 又要循环 很复杂 如果用异或运算符的话 几行代码就搞定

javascript var singleNumber = function (nums) { let n = 0; for (let i = 0; i < nums.length; i++) { n ^= nums[i] } return n; }; const arr = [2,2,1]; console.log(singleNumber(arr)); // 4

这种写法非常简便,而且高效,看起来比较复杂 我们分开几步,一步一步看具体怎么实现的

``` javascript var singleNumber = function (nums) { let n = 0; // for (let i = 0; i < nums.length; i++) { // n ^= nums[i] // } let a = nums[0] let b = nums[1] let c = nums[2]

n = n^a // 0^2 ==> n=2 恒等率 n = n^b // 2^2 ==> n=0 归零率 n = n^c // 0^1 ==> n=1 恒等率 return n; }; const arr = [2,2,1]; console.log(singleNumber(arr)); // 1 另一种情况 javascript var singleNumber = function (nums) { let n = 0; // for (let i = 0; i < nums.length; i++) { // n ^= nums[i] // } let a = nums[0] let b = nums[1] let c = nums[2]

n = n^a // 0^1 ==> n=1 衡等律 n = n^b // 1^3 ==> n=2 交换律 n = n^c // 2^3 ==> n=1 交换律 return n; }; const arr = [1,3,3]; console.log(singleNumber(arr)); // 1

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孙华鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值