php 交换2个变量,不使用第3个变量

首先说明,研究这个并不是想搞什么算法研究,目的在于能够应用到日常的项目代码中。

list

$a = 'A';
$b = 'B';

list($b, $a) = [$a, $b]; //php7可以简写为[$b, $a] = [$a, $b];

echo "a:{$a}, b:{$b}";

建议大家使用list($b, $a) = [$a, $b];的形式,兼容性好,可读性好。

异或

$a = 'A';
$b = 'B';

$a = $a ^ $b;
$b = $a ^ $b;
$a = $a ^ $b;

echo "a:{$a}, b:{$b}";

异或可以理解为是不进位的二进制加法,位相同位0,不同为1,例如

00000101
00000110
------------
00000011

异或满足交换律,即$a ^ $b和$b ^ $a是相同的。
从感性角度讲,异或有点像我们玩的”消消乐“,相同的就”消掉“。比如一个数组[1,1,1,1,2,2,2,3,3],有一个元素出现奇数次,其它元素均出现偶数次,找出这个元素,可以这样实现

$arr = [1,1,1,1,2,2,2,3,3];

$result = $arr[0];
for ($i=1;$i<count($arr);$i++) {
    $result ^= $arr[$i];
}

echo "结果为:{$result}"; // 2

防坑指南

用异或交换2个变量,要明确知道你要交换的2个变量不是同一个变量,比如你通过快慢指针的方式遍历数组,分别是i和j,你要交换$arr[$i]和$arr[$j],代码是这样的

$arr[$i] = $arr[$i] ^ $arr[$j];
$arr[$j] = $arr[$i] ^ $arr[$j];
$arr[$i] = $arr[$i] ^ $arr[$j];

如果i != j没问题,如果i == j,那么说明$arr[$i]和$arr[$j]指向同一个变量,代码本质就变成了下面这样

$a = 1;

$a = $a ^ $a;
$a = $a ^ $a;
$a = $a ^ $a;

你猜猜$a最后等于多少,答案是0。在上面第一次异或操作的时候$a变成0,0 ^ 0还是0。

小结

其实注意到异或也是因为研究算法的时候碰到的,日常coding我们很少用到。但是我想研究了半天,平时不用一下感觉好浪费。不过针对本篇文章来说,我还是建议使用list的方法,语句简单,不用思考是不是同一个变量的问题。

posted @ 2020-08-21 11:25  whyly  阅读(247)  评论(0编辑  收藏  举报