「論理演算」シリーズから、今回はXOR(ビット排他的論理和)の基本をメモ。
🧩 問題ざっくり紹介
入力された 0 と 1 の2つの値をXORして、結果(0または1)を出力。
例:0 1 → 1、 1 1 → 0
✅ 論理和と何が違う?
😵 NG例:論理和で無理やり書いてみた
console.log(A && !B || !A && B);
// → 一応動くけど、読みにくいし型が boolean
✅ OK例:ビット演算でスッキリ
console.log(A ^ B);
// → AとBが「違ってたら1」
JavaScriptでは ^ は ビット単位のXOR演算子。
🔑 ポイント:
- OR(論理和)は どっちかが
1なら1 - XOR(排他的論理和)は 違ってたら
1、同じなら0
おまけ 🔁 応用ワザ3選(全部XORでできる)
- ユニークな値を1個抽出
const arr = [2, 3, 5, 3, 2];
console.log(arr.reduce((a, b) => a ^ b)); // → 5
- フラグのON/OFF切り替え
let flag = 0;
flag = flag ^ 1; // 0→1
flag = flag ^ 1; // 1→0
- 変数スワップ(aとbを入れ替える)
let a = 5;
let b = 10;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log(a, b); // → 10, 5
通常のスワップ([a, b] = [b, a])
※追記: ユニークな値を1個抽出 について
const arr = [2, 3, 5, 3, 2];
console.log(arr.reduce((a, b) => a ^ b)); // → 5
この方法で見つかるのは、「ユニークな値」というより、
「奇数回出現した値」
なんです!!
なぜかというと、
- 同じ値同士を XOR すると 0 になる
- 0 と値を XOR すると、その値そのままになる
から。
たとえば:
2 ^ 2 = 0
3 ^ 3 = 0
0 ^ 5 = 5
こうして、偶数回出現したものは全部消えて、奇数回出たものだけ残るわけですね!
🧪 例:ちょっと複雑な配列
const arr = [2, 3, 2, 5, 2, 5, 3, 5];
console.log(arr.reduce((a, b) => a ^ b)); // → 7
この配列、よく見ると…
- 2 は 3回
- 3 は 2回
- 5 は 3回
つまり、
2 と 5 が「奇数回出現」してる!
そして、2 と 5 を XORすると:
2 ^ 5
計算
2 を2進数で書くと → 10
5 を2進数で書くと → 101
これをXORすると…
010
^ 101
=111
つまり、7!
✅ なので、出力結果は 7 になるんです!
まとめると、
- 偶数回出現する数はXORで打ち消しあう(0になる)
- 奇数回出現する数だけ残る
- 最後に残った数同士をXORする!
🚨 注意点まとめ
ユニークな値(1回だけ出た値)を取り出している
→ 奇数回出現した値を XORでまとめた結果
つまり、
「奇数回出現する値が1個だけ」なら、その値がそのまま結果になる。
でも、
奇数回出現する値が2個以上あると、XORのルールに従ってビット単位で計算された結果になる。
@ffgogfb454 さん コメントで教えてくれてありがとうございました(^^ゞ