【C++】2進表現でセットビット数が奇数になる整数の個数を求める方法
整数 n が与えられたとき、1 から n までの整数の中に、2進表現した際のセットビット(1になっているビット)の数が奇数となるものがいくつあるかを求める問題を解説します。
具体例
入力
n = 10
出力
5
この場合、1 から 10 までの整数のうち、2進表現でのセットビット数が奇数になるものは 5 個あります。
アルゴリズム
整数 N を初期化します。
2進表現におけるセットビットの数を数える関数を作成します。
カウント用の変数を 0 で初期化します。
1 から N まで繰り返すループを記述します。
各整数についてセットビットの数を数えます。
セットビットの数が奇数であれば、カウントを 1 増やします。
最後にカウントを返します。
C++による実装
以下は、上記のアルゴリズムを C++ で実装したコードです。
#include <bits/stdc++.h>
using namespace std;
int getSetBitsCount(int n) {
int count = 0;
while (n) {
if (n % 2 == 1) {
count += 1;
}
n /= 2;
}
return count;
}
int getOddSetBitsIntegerCount(int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (getSetBitsCount(i) % 2 == 1) {
count += 1;
}
}
return count;
}
int main() {
int n = 10;
cout << getOddSetBitsIntegerCount(n) << endl;
return 0;
}実行結果
上記のコードを実行すると、次の出力が得られます。
5
補足:より効率的な実装
セットビットの数を数える処理は、n & (n - 1) を使うことで最下位のセットビットを1回ずつ消去でき、より高速にカウントできます。また、C++20 以降では標準ライブラリの std::popcount を利用することも可能です。
-
C++でセットビット数に基づいて配列をソートする方法
今回は、配列を「セットビット」の数に基づいてソートするという興味深い問題を取り上げます。セットビットとは、数値を2進数で表したときに「1」となっているビットのことです。セットビット数が多い要素ほど、少ない要素よりも前に配置されるように並べ替えます。例として、12・15・7 という3つの数値を考えてみましょう。それぞれの2進数表現とセットビット数は次のとおりです。1100 (12) → セットビット数 21111 (15) → セットビット数 40111 (7) → セットビット数 3これをセットビット数の降順でソートすると、結果は以下のようになります。1111, 0111, 1100 (つま
-
C++でk個のセットビットを持つ数を最大化するために必要な最小フリップ回数
問題文2つの整数 n と k が与えられます。n のビットを反転(フリップ)して、結果の数がちょうど k 個のセットビット(値が1のビット)を持ち、かつ取り得る最大の数になるようにするために必要な、最小のフリップ回数を求めてください。なお、入力は「k が n のビット数より小さい」という条件を満たす必要があります。例n = 9、k = 2 とします。9 の2進表現は 1001 であり、4ビットで構成されています。4桁の2進数の中でセットビットが2個となる最大の数は 1100、すなわち10進数の 12 です。1001 を 1100 に変換するには、2ビットを反転する必要があります。アルゴリズム1