也谈两个变量交换值的算法

<script language=jscript> function toggleDisplay(itemID){ if (itemID.style.display=="block"){ itemID.style.display="none"; } else { itemID.style.display ="block"; } } </script> 最近开始回顾计算机技术中的一些基本概念,比如值交换,排序等等。想起了小学三年级暑假学苹果机时的一本 Basic 教程。我至今还清晰的记得那本书上关于数值交换那节是这样写的:

甲乙两人各有一桶油,一个装了 5 升,一个装了 3 升,他们想把自己桶里的油跟对方换一下,但是不知道怎么办。正好阿凡提骑毛驴经过,听了他们的问题,就说:这好办,我这里也有一个桶。甲把油先倒到我的桶里;乙把油再倒到甲的桶里;我再把油倒到乙的桶里。问题就解决了。

就这么懵懵懂懂接受了变量值交换的这种标准算法(增加一个辅助变量),之后有十多年的时间从没对这个简单的问题加以深究。 临时变量代码示例。
但是不少人不满足常规的解法,要求不借助第三方的力量,通过两个变量之间的捣腾运算来达到目的。我充分理解这种需求,在嵌入式系统编程中,内存还是比较稀罕的,不像现在的 PC 上动辄几个 G。使用异或(Xor)运算符是一种比较奇妙的解法,不需要分配临时变量空间。
Xor(^)运算是一种挺有意思的运算,经常用在文本加密。异或加密是一种对称算法,也就是说用来加密的密钥也是用来解密的密钥,听起来有点像化学上的还原剂。想当年丹麦著名的物理学家玻尔,在二战德军入侵哥本哈根的前夕被迫撤离祖国时,将自己的诺贝尔金牌溶入盛有王水的试剂瓶中。纳粹分子搜查时一无所获。战争结束后,玻尔把铜放入溶液,置换还原出了金块,重新铸成奖牌。听上去是个不错的加密解密故事哦。
Xor 运算有下列一些性质,所以能把操作数还原出来:
  • 交换律(Commutativity) A^B = B^A
  • 结合律(Associativity) (A^B)^C = A^(B^C)
  • 对于任何 A,A^0=A
  • 对于任何 A,A^A=0
Xor 运算代码示例。
不借助第三方变量,除了高深的 Xor 运算外,还可以通过简单的算术运算来达到目的。这个其实连小学生都可以弄出来;可惜当我还是小学生的时候,我被临时变量的解法先入为主了,没有向老师提出这个加加减减的另类算法。我今天写这篇文章,就是为了将来有一天跟女儿说——复杂的问题要往简单里想,简单的问题要往复杂里想。
算术运算代码示例。
但是算术算法受计算机数据存储方式的影响,会发生溢出现象。考虑到大多数情况下要交换的两个变量是同号的,我们可以把代码改成:a=a-b;b=a+b;a=b-a;
网上还有一种指针地址交换的算法,就是让本来指向 a 变量存储地址的指针指向 b 变量存储地址。但是这种算法风险比较大,我就不推荐了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值