不借助第三个变量交换两个整数
2016-08-06 21:40
253 查看
假设两个数x和y,则有:
方法1,算术运算(加减):
方法2,逻辑运算(异或):
关于异或运算要牢记两个原则:
任何一位二进制数同 1 异或都会变成另外一个(0 同 1 异或的结果是 1,1 同 1 异或的结果是 0)
任何一位二进制数同 0 异或都保持不变(0 同 0 异或的结果是 0,1 同 0 异或的结果是 1)
实现这个操作的方法很多。
最基本的方法就是使用一个临时变量,具体的代码如下:
int a,b;
int tmp;
tmp=a;
a=b;
b=tmp;
另外,还经常出现的一种情况是不使用临时变量来交换两个整型数,一般常见的方法有两种:加法和异或运算,具体如下表所示:
左边的两种交换也存在问题就是整数的溢出。
所以更严谨的做法如下:
【扩展】
另外,还有不使用临时变量交换N个整型数的操作,
有N(N>=2)个变量,不使用临时变量,如何顺次交换它们的值?能否只用一条语句实现?如
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+
要把它变为
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+
怎样实现?
首先,我们考虑用异或实现两个变量的交换,可参考我的这篇文章《不用临时变量交换两个数的值》。用C++写函数如下:
然后可以把代码优化为:
继续优化,把三句压缩为一句,如下:
还可再优化,如下:
现在来顺次交换5个变量的值,如下:
既然有返回值,那么可以写成链式的,如下:
现在,让我们来把swap函数依次用相应的函数体替换掉,如下:
方法1,算术运算(加减):
任何一位二进制数同 1 异或都会变成另外一个(0 同 1 异或的结果是 1,1 同 1 异或的结果是 0)
任何一位二进制数同 0 异或都保持不变(0 同 0 异或的结果是 0,1 同 0 异或的结果是 1)
实现这个操作的方法很多。
最基本的方法就是使用一个临时变量,具体的代码如下:
int a,b;
int tmp;
tmp=a;
a=b;
b=tmp;
另外,还经常出现的一种情况是不使用临时变量来交换两个整型数,一般常见的方法有两种:加法和异或运算,具体如下表所示:
void swap1(int& x,int& y) { x=x+y; y=x-y; x=x-y; } | void swap2(int &x,int &y) { x=x-y; y=x+y; x=y-x; } | void swap3(int& x,int& y) { x ^= y; y ^= x; x ^= y; } |
x和y同号的情况下容易溢出 | x和y异号的情况下容易溢出 | |
所以更严谨的做法如下:
void swap4(int &x,int &y) { if(x==y) return ; if((x>0&&y>0)||(x<0&&y<0)) { x=x-y; y=x+y; x=y-x; } else{ x=x+y; y=x-y; x=x-y; } } | void swap5(int &x,int &y) { if(x==y) return; x^=y; y^=x; x^=y; } |
void swap7(int &x,int &y) { if(x==y) return; y=x+y-(x=y); } |
另外,还有不使用临时变量交换N个整型数的操作,
有N(N>=2)个变量,不使用临时变量,如何顺次交换它们的值?能否只用一条语句实现?如
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+
要把它变为
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+
怎样实现?
首先,我们考虑用异或实现两个变量的交换,可参考我的这篇文章《不用临时变量交换两个数的值》。用C++写函数如下:
int &swap(int &a, int &b) { b = b ^ a; a = a ^ b; b = b ^ a; return b; } |
int &swap(int &a, int &b) { b ^= a; a ^= b; b ^= a; return b; } |
int &swap(int &a, int &b) { b ^= a ^= b ^= a; return b; } |
int &swap(int &a, int &b) { return (b ^= a ^= b ^= a); } |
swap(a, b); //返回b swap(b, c); //返回c swap(c, d); //返回d swap(d, e); |
swap(a, b); //返回b swap(swap(a, b), c); //返回c swap(swap(swap(a, b), c), d); //返回d swap(swap(swap(swap(a, b), c), d), e); |
e ^= d ^= e ^= swap(swap(swap(a, b), c), d); e ^= d ^= e ^= d ^= c ^= d ^= swap(swap(a, b), c); e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= swap(a, b); e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a; |
相关文章推荐
- 不借助第三个变量交换两个整数的值
- 不借助第三个变量交换两个整数
- 不借助第三个变量实现两个变量之间的值传递和交换
- 不借助第三个变量实现两个变量交换
- 不借助第三个变量实现两个变量交换的思考
- 为什么异或运算可以实现两个整数的交换,而无需借助第3个临时变量
- 为什么异或运算可以实现两个整数的交换,而无需借助第3个临时变量
- 不使用第三个变量实现两个整数之间的交换
- 不借助第三个变量来交换两个变量的值
- 不借助第三个变量交换两个变量值的方法
- 不借助第三个变量实现两个变量交换的思考
- 不借助第三个变量,交换两个变量值的3种方式
- 异或运用--不借助第三个变量交换两个变量的值
- 关于交换两个整数(不借助第三个临时数)...
- 不借助第三个变量来交换两个变量的值
- 不借助第三个变量交换两个变量的值
- 不借助第三个变量交换两个数值类型变量的值
- 不使用第三个变量完成两个整数的交换
- 基于JAVA的不借助第三个变量实现交换两个变量的值的小代码
- 不借助第三个变量实现两个变量交换的思考