不借助第三个变量交换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的值是一直没有改变过的,
//所以c^a,可以推导出:(a^b)^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 = a^b^b;
再加上括弧;

1.c0=a0^b0;
2.b1=(a0^b0)^b0;
3.a1=(a0^b0)^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,在这个过程中一共值发生了几次变化.

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

GG ... 晚安...

扩展

  • 逻辑运算["~","&","|","^"]

编辑时间列表

[1].二〇一六年十一月十五日 18:17:41
[2].贰零贰零年-一月十五号 晚

原文地址:https://www.cnblogs.com/love-zf/p/12199326.html

时间: 2024-09-29 22:58:59

不借助第三个变量交换a,b两个变量值的相关文章

不借助第三个变量交换两个数值类型变量的值

原文地址:http://blog.csdn.net/web_hwg/article/details/75045689 方法一 最简单的方法是用一个临时变量 var a = 10, b = 20; var temp = a; a = b; b = temp; 方法二 让其中一个变量变成一个与a和b都有关系的值 a = a + b; b = a - b; a = a - b; 或者 a = a - b; b = a + b; a = b - a;

如何不利用一个额外的变量来达到交换两个变量值的目的-------位上的异或运算

问题:一般我们要交换两个变量的值,多会采取一个额外变量来实现,比如temp=a,a=b,b=temp,现在我们能不利用temp来实现交换a,b两个变量值的目的吗? 解决方案:^异或运算符,而且我们会发现a^a=0,还有0^a=a,依据这两条理论,我们可以实现之前提出的问题. 代码如下: #include<stdio.h>void inplace_swap(int * x,int * y){    *y=*x^*y;    *x=*x^*y;    *y=*y^*x;}int main(){  

不借助第三个变量,交换两个变量值的3种方式

今天在我们学校的OJ上做题,一道非常简单的题,突然想试试能不能不借助第三个变量,交换两个变量值.蒙出来一半了已经,好可惜.现在把方法写在这里,希望以后不要忘记. 1 void fun1() 2 { 3 int a = 10, b = 100; 4 5 a = a + b; 6 b = a - b: 7 a = a - b; 8 printf("%d\n%d\n", a, b); 9 } 10 11 void fun2() 12 { 13 int a = 10, b = 100; 14

C# 不借助第三个变量实现两整数交换

c#中实现两个int变量的数值互换,在借助第三个变量做临时载体的情况下,非常简单. int a = 10; int b = 5; int c ; c = a; a = b; b = c; 如果不借助第三方变量,有几种实现的方法: 1.异或算法(这种方法不借助第三个变量,也不会产生溢出,比较安全,但仅限整数类型) int a = 10; int b = 5; a ^= b; b ^= a; a ^= b; Console.WriteLine("{0} {1}", a, b); 2.直接赋

Java基础知识强化05:不借助第三个变量实现两个变量互换

代码如下: package himi.hebao; /** * 不借助第三个变量实现,两个变量互换 * 这里利用^异或实现两个变量的互换 * @author Administrator * */ public class TestDemo08 { public static void main(String[] args) { int a= 120; int b= 34; a= a^b; //进行变量互换 b= b^a; //进行变量互换 a= a^b; //进行变量互换 System.out.

不使用第三个变量交换两个变量的值

交换两个变量(a和b)的值,最简单的办法是另定义一个变量(c),将a赋给c,然后调换. 下面给出几种不使用第三个变量的办法: 1.利用运算交换两个变量值 a = b - a; b = b - a; a = b + a; 2.位运算 通过异或运算来交换值 a=a^b; b=a^b; a=a^b; 3.交换指针地址

不使用临时变量交换两个变量值

题目:不使用临时变量交换两个变量值 分析:使用加.减.乘.亦或(aba==b),四种方法分别如下: //方法一:利用加法 int Swap3(int *x, int *y) { *x = *x + *y;//*x是二者和 *y = *x - *y;//*y是*x *x = *x - *y;//*x是*y } //方法二:利用减法 int Swap1(int *x, int *y) { *x = *x - *y;//*x是二者差值 *y = *x + *y;//*x是*y *x = *y - *x

不使用临时变量 交换两个变量值

不使用临时变量 交换两个变量值1.$a = $a+$b;$b = $a-$b;$a= $a-$b; 2.list($a, $b) = array($b, $a); 3. $a = $a ^ $b;$b = $a ^ $b;$a = $a ^ $b;

JavaScript交换两个变量值的七种解决方案

前言 这篇文章总结了七种办法来交换a和b的变量值 1 2 var a = 123; var b = 456; 交换变量值方案一 最最最简单的办法就是使用一个临时变量了,不过使用临时变量的方法实在是太low了 1 2 3 4 var t; t = a; a = b; b = t; 首先把a的值存储到临时变量中,然后b赋值给a,最后拿出临时变量中的a值赋给b,这个办法是最基本的了 交换变量值方案二 下面的方案都不会有临时变量,我总结了一下,其实不使用临时变量的思路都是让其中一个变量变成一个a和b都有