交换两个整型数是C/C++中最常见的操作。
实现这个操作的方法很多。
最基本的方法就是使用一个临时变量,具体的代码如下:
int tmp;
tmp=a;
a=b;
b=tmp;
如果以函数的形式写出来的话就是:
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
在C++中,可以使用引用来实现的比较优雅:
{
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异号的情况下容易溢出 |
左边的两种交换也存在问题就是整数的溢出。
还有一种情况就是输入是swap(a,a)的情况。这样的话就会出问题。
所以更严谨的做法如下:
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); } |
引申:
在C++中支持模板操作,所以,可以利用这个写一个通用的swap操作:
void swap ( T& a, T& b )
{
T c(a);
a=b;
b=c;
}
这个其实是C++标准模板库中函数。该函数可以交换任意两个类型:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main () {
int x= 10, y= 20; // x:10 y:20
swap(x,y); // x:20 y:10
vector< int> first ( 4,x), second ( 6,y); // first:4x20 second:6x10
swap(first,second); // first:6x10 second:4x20
cout << " first contains: ";
for (vector< int>::iterator it=first.begin(); it!=first.end(); ++it)
cout << " " << *it;
// first contains: 10 10 10 10 10 10
cout << endl;
return 0;
}
除此之外,在标准C++中string,vector,map,set等容器都是有swap函数的。
下面是一些简单的例子:
//
swap strings
#include <iostream> #include < string> using namespace std; main () { string buyer ( " money "); string seller ( " goods "); cout << " Before swap, buyer has " << buyer; cout << " and seller has " << seller << endl; seller.swap (buyer); cout << " After swap, buyer has " << buyer; cout << " and seller has " << seller << endl; // Before swap, buyer has money and seller has goods // After swap, buyer has goods and seller has money return 0; } |
//
swap vectors
#include <iostream> #include <vector> using namespace std; int main () { unsigned int i; vector< int> first ( 3, 100); // three ints with a value of 100 vector< int> second ( 5, 200); // five ints with a value of 200 first.swap(second); cout << " first contains: "; for (i= 0; i<first.size(); i++) cout << " " << first[i]; cout << " \nsecond contains: "; for (i= 0; i<second.size(); i++) cout << " " << second[i]; // first contains: 200 200 200 200 200 // second contains: 100 100 100 cout << endl; return 0; } |
//
swap maps
#include <iostream> #include <map> using namespace std; int main () { map< char, int> foo; map< char, int> bar; map< char, int>::iterator it; foo[ ' x ']= 100; foo[ ' y ']= 200; bar[ ' a ']= 11; bar[ ' b ']= 22; bar[ ' c ']= 33; foo.swap(bar); cout << " foo contains:\n "; for ( it=foo.begin() ; it != foo.end(); it++ ) cout << (*it).first << " => " << (*it).second << endl; cout << " bar contains:\n "; for ( it=bar.begin() ; it != bar.end(); it++ ) cout << (*it).first << " => " << (*it).second << endl; return 0; } foo contains: a => 11 b => 22 c => 33 bar contains: x => 100 y => 200 |
//
swap sets
#include <iostream> #include < set> using namespace std; main () { int myints[]={ 12, 75, 10, 32, 20, 25}; set< int> first (myints,myints+ 3); // 10,12,75 set< int> second (myints+ 3,myints+ 6); // 20,25,32 set< int>::iterator it; first.swap(second); cout << " first contains: "; for (it=first.begin(); it!=first.end(); it++) cout << " " << *it; cout << " \nsecond contains: "; for (it=second.begin(); it!=second.end(); it++) cout << " " << *it; cout << endl; return 0; } first contains: 20 25 32 second contains: 10 12 75 |
另外,还有不使用临时变量交换N个整型数的操作,
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+
|
然后可以把代码优化为:
|
继续优化,把三句压缩为一句,如下:
|
还可再优化,如下:
|
现在来顺次交换5个变量的值,如下:
|
既然有返回值,那么可以写成链式的,如下:
|
现在,让我们来把swap函数依次用相应的函数体替换掉,如下:
|
好了,最后一个语句就实现了顺次交换五个变量的值,写程序验证如下:
#define PRINT(A) do {/
printf( " %d/n ", A);/
} while ( 0)
int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
// b ^= a ^= b ^= a; // swap(a, b)
// c ^= b ^= c ^= b; // swap(b, c)
// d ^= c ^= d ^= c; // swap(c, d)
// e ^= d ^= e ^= d; // swap(d, e)
e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;
PRINT(a);
PRINT(b);
PRINT(c);
PRINT(d);
PRINT(e);
return 0;
}