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

【C++】ビット単位AND演算の結果が奇数になるペアの総数を数える方法

整数型の配列が与えられたとき、配列内の値から組み合わせられるすべてのペアのうち、ビット単位のAND演算(&)を適用した結果が奇数になるペアの総数を求めるのがこの記事の課題です。

AND演算の真理値表

まず、AND演算の挙動を確認しましょう。真理値表は以下の通りです。両方の入力が1のときのみ、結果が1になります。

ABA & B
000
100
010
111

入力例と出力例

入力 − int arr[] = {2, 5, 1, 8, 9}

出力 − ビット単位ANDの結果が奇数となるペアの数: 3

説明 − 配列内のすべてのペアについてAND演算の結果を検証すると、次のようになります。

a1a2a1 & a2
250
210
280
290
511
580
591
180
191
898

このように、結果が奇数(最下位ビットが1)になるペアは「(5, 1)」「(5, 9)」「(1, 9)」の3組です。

アルゴリズム(プログラムで使用するアプローチ)

  • ペアを形成する対象となる整数要素の配列を入力します。
  • 配列のサイズを計算し、後続の処理のためにデータを関数へ渡します。
  • AND演算の結果が奇数となるペアの数を格納する一時変数countを用意します。
  • iを0から配列サイズまでforループで繰り返します。
  • ループ内で、arr[i] % 2 == 1(要素が奇数)であればcountを1増やします。
  • countに「count * (count - 1) / 2」を代入します。
  • countを返します。
  • 結果を出力します。

なぜ「奇数の個数」を数えるだけでよいのか

ポイントは、奇数は2進数表現において最下位ビット(LSB)が必ず1になっているという性質です。AND演算の結果が奇数になるのは、両方のオペランドのLSBが1のとき、すなわち両方の値が奇数である場合に限られます。したがって、配列中の奇数の個数をkとすれば、答えは組み合わせの公式「k × (k − 1) / 2」で一発的に求められます。これにより、全ペアを実際に列挙するO(n²)の計算量を避け、O(n)で処理できます。

コード例

#include <iostream>
using namespace std;
//ビット単位ANDの結果が奇数となるペアを数える
int count_pair(int arr[], int size){
    int count = 0;
    for (int i = 0; i < size; i++){
       if ((arr[i] % 2 == 1)){
           count++;
       }
    }
    count = count * (count - 1) / 2;
    return count;
}
int main(){
    int arr[] = {2, 5, 1, 8, 9, 2, 7};
    int size = sizeof(arr) / sizeof(arr[0]);
    cout<<"Count of pairs with Bitwise AND as ODD number are: "<<count_pair(arr, size) << endl;
    return 0;
}

出力

上記のコードを実行すると、次の出力が生成されます。

Count of pairs with Bitwise AND as ODD number are: 6

配列{2, 5, 1, 8, 9, 2, 7}には奇数が「5, 1, 9, 7」の4個含まれているため、4 × 3 ÷ 2 = 6という結果になります。

  1. C++で配列内の偶数・奇数要素の個数を数える方法

    このチュートリアルでは、配列に含まれる偶数要素と奇数要素の個数を求めるC++プログラムについて解説します。ここでは、あらかじめ整数の配列が与えられているものとします。私たちの課題は、その配列の中に偶数がいくつ、奇数がいくつ含まれているかを正確にカウントすることです。考え方基本的なアプローチは非常にシンプルです。以下の手順で処理を行います。偶数・奇数それぞれのカウント用変数を0で初期化するfor文を使って配列の全要素を先頭から順に走査する各要素を2で割った余り(剰余演算 %)を判定し、余りが0なら偶数、そうでなければ奇数としてカウントする最後に両方の結果を出力するサンプルコード#include&

  2. C++でNとのビット単位AND演算により得られる数値の集合を出力する方法

    この問題では、0からnまでの各整数とnをビット単位AND演算(&)したときに得られる値をすべて求め、重複なく出力します。これらの値は、nの2進表現における「1」のビットを組み合わせた部分集合(部分マスク)に相当します。問題の例具体例を見ながら概念を理解しましょう。入力 : N = 4 出力 : 0 4 説明 : 0 & 4 = 0 1 & 4 = 0 2 & 4 = 0 3 & 4 = 0 4 & 4 = 4 入力 : N = 6 出力 : 0, 2, 4, 6N = 6の場合、6は2進数で「110」と表されます。0から6までの各数値と6のANDを取る