問
交換兩個整形變量的值。通常我們的做法是:定義一個新的變量,藉助它完成交換。
代碼如下:
int a=1;
int b=2;
int t=0;
t=a;
a=b;
b=t;
如何在不借助第3個變量交換兩變量的值?
這是個常見的面試筆試題,題目隨小,但是卻非常巧妙,遇到這個小問題是在同事寫的代碼中,這位優秀同事使用的位運算符 ^
,讓我眼前一亮,於是決定仔細思考並在此記錄下來。
答
有三種常見的方式:
- 利用加法運算
- 利用乘法運算
- 利用位運算
加法交換
void swap1(int* a,int* b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
乘法交換
void swap2(int* a,int* b)
{
*a = *a * *b;
*b = *a / *b;
*a = *a / *b;
}
位運算
void swap3(int* a,int* b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
此算法能夠實現是由異或運算的特點決定的,通過異或運算能夠使數據中的某些位翻轉,其他位不變。
測試 demo
int main(int argc, char const *argv[])
{
int x = 1;
int y = 2;
printf("before swap1 x is %d , y is %d\n",x,y);
swap1(&x,&y);
printf("after swap1 x is %d , y is %d\n\n",x,y);
printf("before swap2 x is %d , y is %d\n",x,y);
swap2(&x,&y);
printf("after swap2 x is %d , y is %d\n\n",x,y);
printf("before swap3 x is %d , y is %d\n",x,y);
swap3(&x,&y);
printf("after swap3 x is %d , y is %d\n\n",x,y);
return 0;
}
C++ 模板函數實現
#include <iostream>
using namespace std;
template <typename T>
void swap1(T* a,T* b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
int main(int argc, char const *argv[])
{
short x = 1;
short y = 2;
cout <<"before swap1 x is "<< x<< " y is "<<y<<endl;
swap1(&x,&y);
cout <<"after swap1 x is "<< x<< " y is "<<y<<endl;
return 0;
}