Chomado's Blog
You Are Reading

XOR演算でswap

0
C#

XOR演算でswap


コードを書いていて, 値を入れ替えるときに,
C#は標準でswap関数は無いようなので,

if (from > to) // from > to だったら入れ替える
{
    var temp = from;
    from = to;
    to = temp;
}

と普通に書いていたら, 先輩が次のようにきれいにしてくれました!

static class math
{
    public static void swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
}
***** func(~~~~)
{
    if (from > to) 
    {
        math.swap(ref to, ref from);
    }
    .....

なるほど, たしかに, swapはこれからも使う気がするから, こっちのほうがいいしコードもきれいになった!(((o(*゚▽゚*)o)))

そして, ついでに XOR で swap する方法も教えてくれました!

a と b を swap したいとき,

a^= b^= a^= b;

で交換できるらしいです(((o(*゚▽゚*)o)))

いったいこれは何をしているのでしょうか!

a ^ b

a XOR b

を表しているそうです.

それで,

a ^= b;

a = a ^ b;

なので,

a ^= b ^= a ^= b;

a ^= b ^= (a ^= b);

a ^= (b ^= (a ^= b));

なのです!

本当にこれでaとbが交換できるのでしょうか,
って, とても気になりました!

ためしてみます!
xor
画像: http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/xor.html

a : 1011
b : 1110

のとき,

a : 1011
b : 1110
a^b : 0101
b^(a^b): 1011 ← a だ!!(((o(*゚▽゚*)o)))

おおお! たしかに b^(a^b) で a が取れています!


Madoka Chomado (ちょまど)

千代田まどかです。よく「ちょまど」と呼ばれます。Microsoft 社員。文系出身プログラマ兼マンガ家です。

(7) Comments

  1. chiguri says:

    配列aのi番目とj番目を入れ替えることを考えてみるとどうでしょう?

  2. ゆっち says:

    この方法なんですが昔の時代のテクニックで今は使わないほうが良いようです。
    エフェクティブJavaに書いてありました。(>_<)

    1. なるほど…
      ありがとうございます!

  3. ten@BottomCoder says:

    まあ仕事では使わない方がいいけどちょまどさんはCodeGolferなのでビット演算も一通り覚えておいた方がいいのではないでしょうか

  4. 匿名 says:

    以前kazu_yamamotoさんあたりがツイートしてらっしゃった気がしますが、
    &a==&b のときにこれを使うとa,b両方の全ビットが0になるというバグがあるので使うべきではないです。

  5. t says:

    kazu_yamamotoさんあたりが以前にツイートしてらっしゃった気がしますが、
    &a==&b の時にこれを使うとa,bの全ビットが0になるというバグがあるので使うべきではないです。

  6. 匿名 says:

    XOR交換云々については知識として知っておく程度でいいと思います。
    実際のコードで使用するのはちょっと。。。
    (可読性が悪い、最適化した際に効率が悪くなる、など)

    昔の記事へのコメント、失礼しました。

ten@BottomCoder へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です