<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這招的我大概就是 ![thonk_owo](https://cdn.discordapp.com/emojis/854191459028828231.png?size=20) wait wut ![thonk_owo](https://cdn.discordapp.com/emojis/854191459028828231.png?size=20) 這種感覺。 總之是個很妙的方法,巧妙運用了XOR的還原特性。