python干货在数据交换值时不推荐使用

白癜风的危害 http://pf.39.net/bdfyy/bdfyc/140813/4447676.html

文章:怎么从细节中提高python代码质量?今天我们来聊聊中间变量。

我们提到,在数据交换值的时候,不推荐使用中间变量,那怎么来交换两个变量的值呢?

在我们编码初期我们是这么解决的:定义一个新的变量,利用它来完成交换。

初期我们可以这么去做,因为这样非常好理解,但是它的缺点也很明显,因为使用了临时变量,这样实在浪费资源。

那么有没有办法不利用这个“第三者”呢,答案是必须的!

接下来我给大家通过四种方法(算法)来实现。

算术运算;指针地址操作;位运算;栈实现。1.算术运算,代码如下:

原理:把m、n看作数轴上的点,围绕两点间的距离来进行计算。

2.指针地址操作,代码如下:

原理:对地址的操作实际上进行的是整数运算

理论上我们是通过运用算术算法类似的运算来实现地址的交换,从而达到交换变量的目的。即:

通过运算m、n的地址果然完成了交换,且m指向了原先n指向的值,n指向原先m指向的值了吗?上面的代码可以通过编译,但是执行结果发生错误!怎么回事啊?兄弟别急,先了解一个概念,操作系统把内存分为几个区域:

系统代码/数据区、应用程序代码/数据区、堆栈区、全局数据区等等。在编译源程序时,常量、全局变量等都会被放入全局数据区,局部变量、动态变量则放入堆栈区。

这样当算法执行到“m=(int*)(n-m)”时,m的值并不是0xh,而是要加上变量m所在内存区的基地址,实际的结果就是:0xfh,其中0xf就是基地址,则是m在该内存区的位移。它是由编译器自己自动添加的。因此导致以后的地址计算都不正确,使得m,n指向所在区的其他内存单元。再者,地址运算不能出现负数,即当m的地址大于n的地址时,n-m就会小于零,系统自动采用补码的形式表示负的位移,由此会产生错误,导致与前面同样的结果。

那怎么办呢,别急!以下是整改后的算法:

算法做的最大改进就是采用位运算中的与运算“int(m)0xffff,因为地址中高16位为段地址,后16位为位移地址,将它和0xffff进行与运算后,段地址被屏蔽,只保留位移地址。这样就原始算法吻合,从而得到正确的结果。

大家看着可能有点不好理解,但是他的好处是:即在交换很大的数据类型时,执行速度比算术算法快。

3.位运算,代码如下:

此算法能够实现是由异或运算的特点决定的,通过异或运算能够使数据中的某些位翻转,其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次,值不变。

4.栈实现,代码如下:

以上算法均实现了不借助其他变量来完成两个变量值的交换,相比较而言算术算法和位算法计算量相当,地址算法中计算较复杂,却可以很轻松地实现大类型(比如自定义的类或结构)的交换。

而从实际的软件开发看,标准算法无疑是最好的,能够解决任意类型的交换问题。




转载请注明:http://www.aierlanlan.com/rzfs/3237.html