交換兩個整型數各種方法總結
交換兩個整型數是C/C++中最常見的操作。
實現這個操作的方法很多。
最基本的方法就是使用一個臨時變數,具體的程式碼如下:
int tmp;
tmp=a;
a=b;
b=tmp;
如果以函式的形式寫出來的話就是:
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
在C++中,可以使用引用來實現的比較優雅:
void swap(int& a,int &b) { int tmp; tmp=a; a=b; b=tmp; }
另外,還經常出現的一種情況是不使用臨時變數來交換兩個整型數,一般常見的方法有兩種:加法和異或運算,具體如下表所示:
|
|
|
x和y同號的情況下容易溢位 |
x和y異號的情況下容易溢位 |
左邊的兩種交換也存在問題就是整數的溢位。
還有一種情況就是輸入是swap(a,a)的情況。這樣的話就會出問題。
所以更嚴謹的做法如下:
|
|
|
引申:
在C++中支援模板操作,所以,可以利用這個寫一個通用的swap操作:
template <class T>
void swap ( T& a, T& b )
{
T c(a);
a=b;
b=c;
}
這個其實是C++標準模板庫中函式。該函式可以交換任意兩個型別:
// swap algorithm example
#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函式的。
下面是一些簡單的例子:
另外,還有不使用臨時變數交換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函式依次用相應的函式體替換掉,如下:
|
好了,最後一個語句就實現了順次交換五個變數的值,寫程式驗證如下:
#include <stdio.h>
#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;
}