您的位置:首页 > 其它

交换两个变量的值,不使用第三变量的6种方法

2016-07-21 23:48 501 查看
(前4种为常见算法,以下代码编程语言均以c++例举,数值类型以int例举)

1.算术

//方法1:加减互逆运算
int a=5,b=3;//需要交换的两个变量
a=a+b;b=a-b;a=a-b;

/*方法2:乘除互逆运算
*(因除法可能获得不了精确结果,且比加减法易进位,容易溢出;所以不推荐此种)*/

int c=5,d=3;//需要交换的两个变量
c=c*d;
d=c/d;
c=c/d;


总结:

优点:无需编程基础,就可理解

缺点:仅限于数字,运算的溢出虽可纠正,但不安全

特点:理论上互逆运算均可完成算术交换变量值,但在不同的编程语言,对同一运算的处理略有不同,推荐用加减法,更保险

2.位运算

int a=5,b=3;//需要交换的两个变量
a=a^b;
b=a^b;
a=a^b;


a^b—异或:将两个数按二进制位运算,在同一位上,相同则为0,不同则为1;eg:1^0=1; 0^0=1; 1^1=0

总结

优点:适应广(可用于所有的基本类型,eg:字符串),运算安全,不会溢出

特点:一个变量 与同一个值 异或两次,值不变

3.地址

int *a,*b;
*a=new int(10);
*b=new int(20); //&a=0x00001000h,&b=0x00001200h
a=(int*)(b-a); //&a=0x00000200h,&b=0x00001200h
b=(int*)(b-a); //&a=0x00000200h,&b=0x00001000h
a=(int*)(b+int(a)); //&a=0x00001200h,&b=0x00001000h</span>


当b-a<0,系统自动采用补码的形式表示负的位移,由此会产生错误,以下为改进

if(a<b)
{
a=(int*)(b-a);
b=(int*)(b-(int(a)&0x0000ffff)); //加上基地址:位移&0x0000ffff

a=(int*)(b+(int(a)&0x0000ffff));
}
else
{
b=(int*)(a-b);
a=(int*)(a-(int(b)&0x0000ffff));
b=(int*)(a+(int(b)&0x0000ffff));
}


总结

优点:适应面全(适应于大类型,eg:自定义类,结构),效率高(因值在内存中没有移动,所以速度快,尤其是大类型)

缺点:操作繁多,难理解

4.栈

int a=5,b=3;//需要交换的两个变量
Stack S;
push(S,a);//将a存入栈S
push(S,b);
a=pop(S);//取出栈S中最后一个元素
b=pop(S);


栈的特点:先进后出

5.字符串

String a="str1",b="str2";//需要交换的两个变量
int bLen=b.length;
a=b+a;
b=a.subString(bLen);//截取bLen位置开始到结尾的字符串
a=a.subString(0,bLen);//截取从0开始到bLen-1位置的字符串


总结:

优点:适应广(可将其他基本类型转换为字符串,交换成功后再换回来)

缺点:操作繁多

特点:利用了字符串的截取,合成

6.重载运算符

将某个运算符重载成具有交换值的功能

标准算法

int a=5,b=3;//需要交换的两个变量
int temp;//临时变量
temp=a;
a=b;
b=temp;


总结:因标准算法可以交换任何类型的值,所以通常是实际开发应用中的首选。

拓展知识

一.操作系统把内存分类成:

A.系统代码/数据区

B.应用程序代码/数据区

C.堆栈区

D.全局数据区等

二.在编译源程序时:

常量、全局变量等都放入全局数据区

局部变量、动态变量则放入堆栈区
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: