文章:[不借助if、switch等語句求兩個數較大的一個](http://blog.csdn.net/u013074465/article/details/42684559)
交換兩個數在排序算法中用的很多:[冒泡排序中](http://blog.csdn.net/u013074465/article/details/44339187) 、[插入排序中](http://blog.csdn.net/u013074465/article/details/42043665)等等。正常的交換兩個數是借助一個變量tmp:
~~~
void Swap(int &a, int &b) {
int tmp = a;
a = b;
b = tmp;
}
~~~
在面試題中有這樣的題目“不借助第三個變量,交換兩個數”
~~~
//A方法
void Swap(int &a, int &b) {
a = a + b;
b = a - b;
a = a - b;
}
~~~
~~~
//B方法
void Swap(int &a, int &b) {
a ^= b; b ^= a; a ^= b;
}
~~~
上述的兩種方式中,A方法缺點:中當數a或b較大時 a = a + b會發生越界。
方法B的原理:
~~~
a = a ^ b;
b = a ^ b; //那么 b = a ^ b = (a ^ b) ^ b = a ^ (b ^ b) = a ^ 0 = a,即將a賦值給了b
a = a ^ b; //那么 a = a ^ b = a ^ (a ^ b) = (a ^ a) ^ b = 0 ^ b = b,即實現了將b賦值為a
~~~
以上兩種方法的共有bug:
?????? 當a、b指向的是同一個數時,即Swap(a, a)時,會發生錯誤,將a置為了0。但是a等于b的情況下(即a和b不是指向同一個地址時)是不會錯誤的。
解決方法:
為Swap函數增加判斷語句:當a和b相等的時候不交換。
~~~
//A方法
void test(int &a, int &b) {
?if (a != b) {
??? ?a = a + b;
??? ?b = a - b;
??? ?a = a - b;
??? ?cout << "OK " << endl;
?}
}
//B方法
void Swap(int &a, int &b) {
if (a != b) {
?a ^= b;
b ^= a;
a ^= b;
}}
~~~
- 前言
- Josephus約瑟夫問題及其變種
- 鏈表的常見實現
- 二叉樹遍歷、插入、刪除等常見操作
- 二叉堆的插入刪除等操作C++實現
- 插入排序和希爾排序
- 堆排序
- 歸并排序及其空間復雜度的思考
- 快速排序的幾種常見實現及其性能對比
- 紅黑樹操作及實現
- 整數的二進制表示中1的個數
- 位操作實現加減乘除四則運算
- 冒泡排序的改進
- 直接選擇排序
- 不借助變量交換兩個數
- 基礎排序算法總結
- AVL樹(Adelson-Velskii-Landis tree)
- avl樹的C++實現
- 動態規劃之鋼條分割
- hash函數的基本知識
- 動態規劃:求最長公共子串/最長公共子序列
- 最長遞增子序列
- 稱砝碼問題
- 汽水瓶
- 字符串合并處理(二進制位的倒序)
- 動態規劃:計算字符串相似度
- m個蘋果放入n個盤子
- 生成k個小于n的互不相同的隨機數
- 棧和隊列的相互模擬
- 字符串的排列/組合
- KMP(Knuth-Morris-Pratt)算法
- n個骰子的點數
- 位運算的常見操作和題目