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

(前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

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

if(aint*)(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.全局数据区等

二.在编译源程序时:

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

局部变量、动态变量则放入堆栈区

你可能感兴趣的:(js基础知识,经典例题)