20

XORを使用して、3番目の変数を使用せずにJavaで2つの整数を交換するコードをいくつか試しました。

私が試した2つのスワップ機能は次のとおりです。

package lang.numeric;

public class SwapVarsDemo {

    public static void main(String[] args) {
        int a = 2984;
        int b = 87593;
        swapDemo1(a,b);
        swapDemo2(a,b);
    }

    private static void swapDemo1(int a, int b) {
        a^=b^=a^=b;
        System.out.println("After swap: "+a+","+b);
    }

    private static void swapDemo2(int a, int b) {
        a^=b;
        b^=a;
        a^=b;
        System.out.println("After swap: "+a+","+b);
    }

}

このコードによって生成された出力は次のとおりです。

After swap: 0,2984
After swap: 87593,2984

私は知りたいのですが、なぜこの声明があるのですか:

        a^=b^=a^=b;

これとは違う?

        a^=b;
        b^=a;
        a^=b;
4

6 に答える 6

7

a ^= b ^= a ^= b;次のように解析されるため:

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

これは次のように削減できます。

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

したがってb、値がb ^ (a ^ b)あり、最終的にaは になりますa ^ (b ^ (a ^ b)

于 2014-02-26T14:27:05.197 に答える
2

演算子の優先順位を確認します (参照: http://introcs.cs.princeton.edu/java/11precedence/ Java 演算子の優先順位を検索した結果)。Oracle ドキュメントへの参照は、ここ ( http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html ) に表示されますが、少し複雑です)。

特に、^= は右から左に処理されます (左から右ではありません)。

于 2014-02-26T14:29:35.233 に答える
1

ネイサンの答えにコメントするのに十分な評判ポイントがありません。

Java Puzzlersの本について話している@Nathan Hughesの回答は的を射ており、彼の回答は、これを1行で実行できるいくつかの洞察を示しています。OPの質問ほどエレガントではありませんが。

ネイサンが指摘するように:

CleverSwap プログラムでは、変数 x は 2 回 (式に出現するたびに 1 回) サンプリングされますが、どちらのサンプリングも代入の前に行われます。

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.htmlをガイドとして使用するだけでなく、次のように 1 行でこれを行うことができます。

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

キーは、最初の XOR の一部としての変数値の割り当てであり、2 番目の XOR の左側にそれを保持することを保証します (左側のオペランドでの割り当ての良い例については、上記の jls リンクを参照してください)。同様に、2 番目の XOR の結果を使用して b 変数を設定し、最後の XOR の左側を維持します。

于 2015-08-19T04:55:42.743 に答える
0

2 番目のバリアントは次と等しい

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

于 2014-02-26T14:21:19.263 に答える