2010年10月1日 星期五

不使用 temp 變數交換兩個整數

在交換兩個整數時往往需要一個暫存變數,舉例如下。


int main()
{
  int nA = 170, nB = 240;
  int nTemp;
  nTemp = nA;
  nA = nB;
  nB = nTemp;
  return TRUE;
}


而布林運算中的 XOR 有個 "可逆" 的特色,
看看這 3 條運算式,我們可以利用 C 再與 A 或 B 做 XOR 的方式得到另一個變數,
A ^ B = C
C ^ A = B // 可逆
C ^ B = A // 可逆

將等號移到左邊,改變一下變數,我們就可以把整理成下面的式子

A = A ^ B // 運算後將 C 值給 A
B = A ^ B // 因為 A 變成 C 所以右式是 C ^ B,所以產生出原本 A 的值給 B
A = A ^ B // A 還是 C,但 B 變成了原本的 A,所以運算出原本B的值給 A

簡單的 C++ 範例如下


int main()
{
  int nA = 170, nB = 240;
  swap(&nA, &nB);
}

void swap(int *n, int *m)
{
  // 利用 call by address 的方式改變主函數中的值
  *n = *n ^ *m;
  *m = *n ^ *m;
  *n = *n ^ *m;
}


這是一個很早之前在別人的網頁上看到的技巧,
但 xor 只適用於整數、布林值,這可以說只是用來炫技的耍花槍技巧,
反而依 framework 的不同會比使用 temp 慢上幾倍,
比較好的方式還是使用樣板的方式實作一個萬用 swap function


template <typename AnyType>
void Swap(AnyType &n, AnyType &m)
{
  // 利用 call by reference 方式改變主函式的變數值
  AnyType temp;
  temp = n;
  n = m;
  m = temp;
}

int main()
{
  CString strA = _T("正"), strB = _T("歪");
  Swap(strA, strB);
  return TRUE;
}


如此不論是整數、布林、字串、任何類別都可以使用這個 swap function了。

沒有留言:

張貼留言