不借助第三个变量交换a,b两个变量值

从一个面试题说起...

不借助第三个变量交换a,b两个变量值

一个很经典的答案是通过异或来解决


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

关键字


[
    "异或",
    "逻辑运算符",
    "乔治·布尔",
    "香农"
]

先决条件

0为假,1为真

    插曲>>>如果读到"0为假,1为真",心底肯定略过了,这谁都知道的啊...
但是如果是写出来,但是找不到出处.即使常识也不太肯定了...

"^":对应逻辑运算异或(XOR)。
重点在"异",只有[1]XOR[0]或[0]XOR[1]才为1;一真一假即真;

a ^ a = 0 ;
a ^ 0 = a ;

先决条件.出处和推导

0为假,1为真

香农已经知道,数学上有一种逻辑代数系统,叫做布尔逻辑,它得名于英国数学家乔治·布尔(George Boole)。在布尔逻辑中,任何逻辑表达式的计算结果都不是数值,而是“真”、“假”这两种真值。你只需要使用逻辑运算符“与”、“或”、“非”,就可以表达任何你想表达的逻辑语句。

在逻辑中,真值或逻辑值是指示一个陈述在什么程度上是真的。在计算机编程上多称作布尔值。在经典逻辑中,唯一可能的真值是真和假。但在其他逻辑中其他真值也是可能的。

强行补充一波,如果你非要想让"1为假,0为真",请搜索:"负逻辑".
关于真假由来,我只能找这么多了...

a ^ a = 0 ;a ^ 0 = a ;

二进制的运算


    0110
^  0000
------------
=  0110

再来谈下两个变量的交换.

其实虽然变量值还是[a,b]
但是值可能会出现3个的.

举个栗子↓

a的值 b的值 出现的值
0 0 [0]
0 1 [0,1]
9 5 [9,5,12]
... ... ...

第一步a=a^b;此时,相当于将a和b绑定一下关系.
只有两个变量,没有第三者插足,要交换两个变量的值,不绑定关系,不可能凭空交换吧...

数据库角度考虑的话,类似,表A和表B本来是没有关系的,
但是又想交换两个表之间的数据,还不允许有第三张表的出现,
这个时候,更改了表A的结构.增加了一列.(插入这段话,希望不会让不懂的人更晕了...)

从关系角度来看:

1.建立关系a,此时的a已经变了...
2.根据关系,给b赋值为a,b←a,工作完成了50%
3.根据关系,给a赋值为b,a←b.

从更改状态来看:

1.a进化为a(状态1);b保持原状态;
2.b进化成最终状态b(状态1),即:a;
3.a再次进化成最终状态a(状态2),即:b;

从刚开始用3个变量,再用公式推导消除一个变量来看:

此时共有变量[a,b,c]

1.c=a^b;
2.b=a;
//其实到第3步运行之前,a的值是一直没有改变过的,
//所以ca,可以推导出:(ab)^a,这个时候要注意了,
//此时的b还是在c中的b,而不是第2步已经改变了值得b.(这不是引用类型...不是第2步b的值改了,c的值也跟着改)
//这个地方不太好理解,中心思想就是:先把a和b的关系放兜里,这个兜就是c,并且能通过一种运算,和未改变的a值,
//来反求出b的值;
3.a=c^a;

先将第2步"b=a;",修改一下
因为a^0 = a;可以写为:b=a^0;
因为b^b = 0;可以写为:b = abb;
再加上括弧;

1.c0=a0^b0;
2.b1=(a0b0)b0;
3.a1=(a0b0)b1;

其实这个时候,将c替换成a,是完全可以的,
因为c除了第1步被赋值之后,就没有再改过值.
//a0和a1都是变量a,只是为了区分a值改变了一次,就会将a0写为a1

1.a1=a0^b0;
2.b1=a1^b0;
3.a1=a1^b1;

一共3个赋值动作,第1个赋值为了建立关系,剩下2个,就是赤裸裸的交换数据了.

感受一下,a和b,在这个过程中一共值发生了几次变化.

感觉最后两步讲的还是有点模糊,希望哪位大虾给完善下...

Visual Studio C# Interactive

> var a = 5; var b = 9;

. Console.WriteLine("b = {0}",(a ^ b) ^ b);
. Console.WriteLine("a = {0}",(a ^ b) ^ a);

//输出
a = 9
b = 5
> 
```

![](https://img2018.cnblogs.com/blog/533973/202001/533973-20200117092636069-2110441739.png)



GG ... 晚安...

### 扩展
* 逻辑运算["~","&","|","^"]

 
### 编辑时间列表
[1].二〇一六年十一月十五日 18:17:41
[2].贰零贰零年-一月十五号 晚
posted @ 2020-01-16 00:00  zh89233  阅读(2204)  评论(0编辑  收藏  举报