C++で32ビット符号なし2進数のセットビット(1の個数)を数える方法
32ビットの符号なし2進数が与えられたとき、その中に含まれる「セットビット」、つまり「1」が何個あるかを数えるのが本記事のテーマです。
問題の例
入力:
N = 00000000000000100111
出力:
4
説明: 与えられた符号なし2進数に含まれるセットビット(1)の合計は4個です。したがって、答えとして「4」を返します。
解き方のアプローチ
この問題は、与えられた32ビットの符号なし2進数の中に「1」がいくつ現れるかを数えるものです。
C++では、ビット数を数えるための便利な手段が標準およびコンパイラ拡張として用意されています。代表的な方法は次の2つです。
- std::bitset の count() メンバ関数: 数値を
bitset<32>に変換し、count()を呼び出すだけでセットビットの個数が取得できます。標準ライブラリのみで動作するため、環境を選ばないのが利点です。 - __builtin_popcount(n) 関数: GCC / Clang で使える組み込み関数で、引数 n に含まれる「1」の個数を返します。ハードウェア命令を利用するため非常に高速です。
処理の流れは以下のとおりです。
- 2進数 N を入力として受け取ります。
- 関数 count1Bits(uint32_t n) が32ビットの符号なし整数を受け取り、その中の「1」の個数を返します。
- 内部では bitset の count() または __builtin_popcount(n) を呼び出して結果を取得します。
実装例
#include <bits/stdc++.h>
using namespace std;
int count1Bits(uint32_t n) {
return bitset<32>(n).count();
}
int main() {
// 2進数リテラル(0b接頭辞)で 00000000000000100111 を表現
uint32_t N = 0b00000000000000100111;
cout << count1Bits(N) << endl;
return 0;
}上記のコードを実行すると、次の出力が得られます。
出力
4
与えられた数には「1」が4個含まれているため、出力は「4」になります。
補足:__builtin_popcount を使う場合
GCC系コンパイラを使用している場合は、次のように書くこともできます。
int count1Bits(uint32_t n) {
return __builtin_popcount(n);
}C++20以降では、標準ライブラリの std::popcount(ヘッダー <bit>)も利用でき、より移植性の高いコードを書けます。用途や環境に応じて最適な方法を選びましょう。
-
C++で列車の停車駅の組み合わせ数を求める方法
地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない
-
C++で二分木の各ノードのセットビット数を出力する方法
二分木が与えられたとき、本記事で紹介する関数は、各ノードに格納されたキーの値を2進数に変換し、その2進表現に含まれるセットビット(1)の個数を返します。例キーとして 10、3、211、140、162、100、146 を持つ二分木を考えてみましょう。各キーの2進表現とセットビット数は以下のようになります。キー2進表現セットビット数(出力)101010230011221111010011514010001100316210100010310011001003146100100103__builtin_popcount 関数についてここでは GCC が提供する組み込み関数 __builtin_pop