还得从一个很经典的面试题说起:不通过第三个变量来交换两个变量a,b的值...
一个很经典的答案是通过异或来解决:
第壹步:a=a^b;
第贰步:b=a^b;
第叁步:a=a^b;
以前提起“异或”运算,真的很疑惑?
今天看到“布尔代数简介”,再次看到这个异或运算,才知道异或运算符"^"和“&”和“|”一个级别...
好吧,大家一起来温习下"~"、"&"、"|"、"^"...【0为假,1为真】
"~":对应逻辑运算NOT,非。{比如:~0=1或者~1=0},'~真'即假,'~假'即真;
"&":对应逻辑运算AND,这个大家一定都熟悉。[0]AND[0或者1]都为0,所以只有[1]&[1]=[1];一假即假;
"|":对应逻辑运算OR。[1]OR[0或者1]都为1,所以只有[0]|[0]=[0];一真即真;
"^":对应逻辑运算异或(XOR)。重点在"异",只有[1]XOR[0]或[0]XOR[1]才为1;一真一假即真;
布尔运算[&|^]和整数运算符[+-*/]有很多相同的属性。
由于"一真一假即真",所以0^0=1^1=0,扩展到二进制1111^1111=0000,并且1111^0000=1111,
想想一年级的加法运算(每位相加):
+ ------- =
所以:
^ ------------ =
所以a^a = 0, a ^ 0 = a ;
这下再讲异或交换两个变量就好理解了吧···
并且答案一般都是直接给异或过程的,就如刚开始那样,要不就是一边过程计算一边讲解,这样最多就是讲了每一步的原因,没讲到为什么要这样的步骤...
倒着推或许更好理解点,只要小学学会乘法/加法交换律就行了...
第0步:最后的结果就是a = b ,b = a ;
第1步:a = b ^ 0 = b ^ (a ^ a) = a ^ a ^ b; b = a ^ 0 = a ^ ( b ^ b) = a ^ b ^ b; (0为什么要消除?因为不能出现第三个变量啊,只能a和b)
第2步:发现上步a和b的最终形态都有a^b,先将a ^ b赋值给a或者b,大家貌似都是赋值给a了,咱也这样吧,(只能这么办了,不能第三个变量啊...) ;
a = (a ^ b) ;先求a的吧,a =a ^a ^b = a ^ a =0,,,,貌似不能先求a啊,再先试试来求b吧,如果b还求不出来,那么将a^b赋值给a是行不通的,
b = a^b^b=(a^b)^b=a^b(好吧,不为0,在重第0步开始看,能推到这步就行了;)
第3步:a =a^a^b;上步将a^b赋值给a了,(现在上步的a的作用还是类似第三个变量),上步将b=a了,所以a=a^a^b = a^b^a=(a^b)^a=a^b
(刚开始想的第二步刚开始a=a^b,然后b=a,那么a=a^b也改变值了,,把b当做引用类型了,自己把自己绕晕了...)
感觉最后两步讲的还是有点模糊,希望哪位大虾给完善下...
GG ... 晚安...
编辑二〇一六年十一月十五日 18:17:41