(较全的尝试)c++两数交换

交换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++交换两个数总结

多数算法竞赛中是比谁更好解决问题,只考察程序解决问题的能力,不关心采用了什么方法,不看谁写的程序看上去更高级。

因此竞赛中两数字交换直接cout<<b<<a;就好,当然不会这么简单,体会思想emm
如有问题评论讨论哦~

猜你喜欢

转载自blog.csdn.net/gulaixiangjuejue/article/details/80046133