交换a,b两个数的值:
1、 最普通做法:三变量法
t = a;
a = b;
b = t;
2、 不借助变量
注意到a = a+b-b ; b =a+b-a;
那么可以有:
a = a+ b//结果:a =a0+b0,a0 和b0为初始值
b=a-b//结果:b=a0
a = a-b//结果:a = b0
特征:
适用面比较窄,定义了加减法的数据结构才可以使用,而且a+b不能溢出
对于难以理解的问题可以手工记录每条语句执行后各个变量的值。
3、 位运算:
下面介绍用位运算:异或来进行两数交换。异或运算(相同位为0,不同位为1)满足交换律和结合律,并且有:
a^a = 0;
0^a = a;
a = a^b;//a = a0^b0 b = a^b//b=a0^b0^b0 = a0 a = a^b//a=a0^b0^a0= b0
等价的表示方法:
a ^= b;
b ^= a;
a ^= b;
特征:
有的文章说异或交换的方法在两个数相等的情况下不适用,这句话是有漏洞的。
#include<iostream> using namespace std; void aExchange(int &a, int &b) { /*a = a^b; b = a^b; a = a^b;*/ a ^= b; b ^= a; a ^= b; } int main() { ios::sync_with_stdio(false); cin.tie(0); int a[2] = { 1,1 }; aExchange(a[0], a[1]); cout << a[0] << a[1] << endl; getchar(); }
输出结果还是1,1。
但若将 aExchange(a[0],a[1])改为 aExchange(a[0],a[0]),对应输出结果就是0,0.
因为主函数和aExchange()之间参数传递方式为引用传递,形参里面是实参的地址,对形参的改变会通过间接寻址访问主函数中的实参变量,因此会对主函数中的变量造成影响。
有一篇讲c/c++参数传递个人认为比较透的文章:
也就是说,并不是两个值相等的数字不能用这种方法,而是用来交换的两个不能是位于同一个地址的变量。
#include<iostream> using namespace std; void aExchange(int &a, int &b) { /*a = a^b; b = a^b; a = a^b;*/ a ^= b; b ^= a; a ^= b; } int main() { ios::sync_with_stdio(false); cin.tie(0); int a=1; aExchange(a, a); cout << a << endl; getchar(); }
输出a为0.
因为在这种情况下aEchange方法里实际上是a自身做了三个异或。
此外一些用来两数交换的方法:
C++交换两个数总结
C++交换两个数总结
多数算法竞赛中是比谁更好解决问题,只考察程序解决问题的能力,不关心采用了什么方法,不看谁写的程序看上去更高级。
因此竞赛中两数字交换直接cout<<b<<a;就好,当然不会这么简单,体会思想emm。
如有问题评论讨论哦~