<style>
html, body, .ui-content {
background-color: #333;
color: #ddd;
}
body > .ui-infobar {
display: none;
}
.ui-view-area > .ui-infobar {
display: block;
}
.markdown-body h1{
color: #9CCEF2;
}
.markdown-body h2,
.markdown-body h3{
color: #B1D6CA;
}
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
color: #ddd;
}
.markdown-body h1,
.markdown-body h2 {
border-bottom-color: #ffffff69;
}
.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
color: #fff;
}
.markdown-body img {
background-color: transparent;
}
.ui-toc-dropdown .nav>.active:focus>a, .ui-toc-dropdown .nav>.active:hover>a, .ui-toc-dropdown .nav>.active>a {
color: white;
border-left: 2px solid white;
}
.expand-toggle:hover,
.expand-toggle:focus,
.back-to-top:hover,
.back-to-top:focus,
.go-to-bottom:hover,
.go-to-bottom:focus {
color: white;
}
.ui-toc-dropdown {
background-color: #333;
}
.ui-toc-label.btn {
background-color: #191919;
color: white;
}
.ui-toc-dropdown .nav>li>a:focus,
.ui-toc-dropdown .nav>li>a:hover {
color: white;
border-left: 1px solid white;
}
.markdown-body blockquote {
color: #bcbcbc;
}
.markdown-body table tr {
background-color: #5f5f5f;
}
.markdown-body table tr:nth-child(2n) {
background-color: #4f4f4f;
}
.markdown-body code,
.markdown-body tt {
color: #eee;
background-color: rgba(230, 230, 230, 0.36);
}
a,
.open-files-container li.selected a {
color: #5EB7E0;
}
</style>
###### tags: `雜~~瓦魯多~~筆記`
# 精神污染的swap
交換兩變數值的swap方法百百種,~~其中還有很精神污染的XOR大法~~,嘎油。
[TOC]
## 小心變數值被覆蓋!
如果是很直覺的打出這東西,那你就掉到陷阱裡ㄌ:
```cpp=
int x=1,y=2;
x=y;
y=x;
```
在第3行的 `x=y` 執行後, `x` 的值會變為2,但 `y` 的值也還是2,這就讓兩個都變為原本 `y` 的值2了。
所以正確做法應該是要再開一個變數,來儲存原本x的值:
```cpp=
int x=1,y=2;
int temp;
temp=x;
x=y;
y=temp;
```
## swap()
c++有內建swap函式,可以直接交換兩變數值。
```cpp=
int x=1,y=2;
swap(x,y);
```
## XOR
在這裡要先來講講XOR(exclusive or)是啥。
XOR在c++裡的運算符號是 `^` ,運算關係可以用以下方式呈現:
| | 0 | 1 |
| ----- | - | - |
| **0** | 0 | 1 |
| **1** | 1 | 0 |
而依此規則,兩數XOR的運算如下例:
設x=188,y=85
先將兩者轉為二進位,x=10111100,y=01010101
| x | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
| --- | - | - | - | - | - | - | - | - |
| **y** | **0** | **1** | **0** | **1** | **1** | **0** | **1** | **0** |
| x^y | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
可得到 `x^y` 的值為11100110。
那如果再把 `x^y` 的值再 `^y` 一次...
| x^y | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
| --- | - | - | - | - | - | - | - | - |
| **y** | **0** | **1** | **0** | **1** | **1** | **0** | **1** | **0** |
| | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
可以看到值變回 `x` 了。
如果 `x\^y` 再 `^x` 則是...
| x^y | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 |
| --- | - | - | - | - | - | - | - | - |
| **x** | **1** | **0** | **1** | **1** | **1** | **1** | **0** | **0** |
| | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
可由以上範例,觀察出 XOR 會有以下關係:
```
(x^y) ^ y = x
(x^y) ^ x = y
```
只要對同個數 XOR 兩次,就會變回原本的數字
所以!神奇的事要來ㄌ!
```cpp=
int x=1,y=2;
x = x^y; //X現在為1^2
y = x^y; //y現在為(1^2)^2,也就是1
x = x^y; //x現在為(1^2)^1,也就是2
cout << "x=" << x << "\ny=" << y;
```
輸出如下:
```
x=2
y=1
```
第一次看到XOR這招的我大概就是  wait wut  這種感覺。
總之是個很妙的方法,巧妙運用了XOR的還原特性。