Generate...|

园龄:粉丝:关注:

2022-10-27 11:50阅读: 62评论: 0推荐: 1

三次异或交换数字

三次异或交换数字

在本文表示异或

void swap(int * restrict x, int * restrict y)
{
if (x == y) return;
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
// *y ^= *x ^= *y ^= *x;
}

三种证明方式:

  1. 将所有可能写出来

01001110

只考虑一位的情况,可以看出三次异或后,位交换了。而整数也是多个位组成的,自然可以交换。

  1. 从正常交换的过程思考

    正常交换数值时,需要一个值来保持中间变量。虽然没有直接声明一个变量来保持,但其实y就已经作为中间变量了。我将作为中间变量的y写作y'

    第一次异或:y'保存了xy不同的位(异或就代表着不同);
    第二次异或:一个位异或0值不变,异或1则取反。此时y'中保存着原来的y不同于x的位,所以y'x中不同于y的位都取反了,x也就变成了y
    第三次异或:x现在是y了,成功交换了。那么将y中不同于x的位取反(仍然通过y'),y'也就变成了x

  2. 列表写逻辑值

    *x = a, *y = b

    aa=00a=a1a=a

    stepxy0ab1aab2bab3ba

虽然思路很巧妙,但是异或开销大,比传统的交换慢上很多。

实际上,可以用加减代替异或

void swap(int * restrict x, int * restrict y)
{
if (x == y) return;
*y = *x - *y;
*x -= *y;
*y += *x;
// *y += *x -= *y = *x - *y;
}

使用加减的交换过程比较好验证,也有其他更多写法,总之是三步完成交换。不过使用加减会出现溢出问题。

本文作者:violeshnv

本文链接:https://www.cnblogs.com/violeshnv/p/16831723.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Violeshnv  阅读(62)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 とおいよびごえ 凋叶棕
  2. 2 かぜのねいろ 凋叶棕
  3. 3 Milky Way Train 流派未階堂
  4. 4 nostalgia 流派未階堂
  5. 5 桜花繚乱 はちみつれもん
  6. 6 胡蝶之夢 はちみつれもん
  7. 7 色は散りゆく はちみつれもん
  8. 8 暮色蒼然 はちみつれもん
  9. 9 追想、桜ノ國 はちみつれもん
  10. 10 意にそぐわぬリターニー 凋叶棕
Milky Way Train - 流派未階堂
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.