C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でXOR演算子を使わずに2つの数値のXORを求める方法

この問題では、2つの整数値 A と B が与えられ、XOR演算子(^)を使用せずに両者のXORを求めることが課題となります。

具体例で問題を確認してみましょう。

入力 : A = 4, B = 5
出力 : 1

解法アプローチ1:ビットごとの演算を利用する

まず、各数値を2進数に変換し、次の真理値表に基づいてビット単位の演算を行う方法があります。

AB出力
000
011
101
110

この表は、両方のビットが同じ場合に0、異なる場合に1を返す、まさにXORの動作そのものです。AND・OR・NOTなどの基本的なビット演算だけを組み合わせることで、この結果を実現できます。

実装例

上記の解法の動作を示すプログラムです。

#include <iostream>
using namespace std;
int calcXORwoOperator(int a, int b){
    int xorVal = 0;
    for (int i = 31; i >= 0; i--){
        bool val1 = a & (1 << i);
        bool val2 = b & (1 << i);
        bool xorBit = (val1 & val2) ? 0 : (val1 | val2);
        xorVal <<= 1;
        xorVal |= xorBit;
    }
    return xorVal;
}
int main(){
    int a = 4, b = 5;
    cout<<"XOR of the numbers is "<<calcXORwoOperator(a, b);
   return 0;
}

出力

XOR of the numbers is 1

このプログラムでは、上位ビットから順に各ビットを取り出し、両方のビットが1の場合は0、それ以外の場合はOR演算の結果を設定することで、XORと同等の処理を実現しています。

解法アプローチ2:論理式を利用する(より簡潔な方法)

もうひとつの方法として、2つの数値の対応するビットを1つずつ比較し、XORと同等の演算を行うアプローチがあります。

ポイントとなるのは、次の論理式です。

(a | b) - (a & b) ≡ a ^ b

この式が成り立つ理由は以下の通りです。

  • (a | b):少なくとも片方のビットが立っている位置がすべて1になります。
  • (a & b):両方のビットが立っている共通部分のみが1になります。

ORの結果からANDの結果を引くと、「片方だけが1であるビット」だけが残ります。これはXORの定義と完全に一致します。この式を使えば、ループも不要で、たった1行でXORを求められます。

実装例

上記の解法の動作を示すプログラムです。

#include <iostream>
#include <bitset>
using namespace std;
int calcXORwoOperator(int a, int b) {
   return (a | b) - (a & b);
}
int main(){
   int a = 4;
   int b = 5;
   cout<<"The XOR of both numbers is "<<(bitset<8>(calcXORwoOperator(a, b)));
   return 0;
}

出力

The XOR of both numbers is 00000001

まとめ

XOR演算子を使わずに2つの数値のXORを求めるには、主に2つの方法があります。

  1. ビットごとの演算:各ビットを取り出して真理値表に従って計算する。ロジックの理解に役立ちます。
  2. 論理式 (a | b) - (a & b):シンプルかつ効率的で、実務向きの手法です。

どちらの方法もXORの本質である「異なるビットだけが1になる」という性質を活かしたものです。面接や競技プログラミングでも頻出のテーマなので、ぜひ覚えておきましょう。

  1. C++で「-」演算子のオーバーロードを使って2つの数値を加算する方法

    演算子オーバーロードは、C++における重要な概念の一つです。これはポリモーフィズム(多態性)の一種であり、演算子にユーザー定義の意味を持たせるためにオーバーロードする仕組みです。オーバーロードされた演算子は、ユーザー定義のデータ型に対して操作を実行するために使用されます。例えば、「+」演算子をオーバーロードすることで、整数型や文字列型(連結処理)など、さまざまなデータ型に対して加算を行うことができます。入力と出力入力10 20 20 30出力30 50処理の解説このプログラムでは、「-」演算子をオーバーロードして、2つの数値の加算を実現します。二項演算子は操作を実行するために1つのオブジェクト

  2. 【C言語】演算子を使わずに2つの数値の合計を求めるプログラム

    この記事では、C言語のプログラムにおいて+演算子などの演算子を一切使わずに、2つの数値の合計を求めて出力する方法を解説します。一見すると手強そうな問題ですが、printf()関数の「最小フィールド幅」指定を利用することでエレガントに解決できます。printf()では、書式指定子の * を使うことで、可変引数からフィールド幅(出力する最小文字数)を動的に受け取ることができます。例えば、「Hello」という文字列の前にx個の空白を挿入したい場合は、次のように記述します。サンプルコード#include<stdio.h> main() {     i