C++である数値のセットビットと未セットビットの数が同じかどうかを判定する方法
この記事では、ある整数の2進数表現において、セットビット(1となっているビット)と未セットビット(0となっているビット)の数が同じかどうかを判定する方法を解説します。
例として、数値12を考えてみましょう。12の2進数表現は「1100」です。この中には1が2つ、0が2つ含まれており、セットビットと未セットビットの数が一致しています。
アルゴリズムの考え方
アプローチは非常にシンプルです。以下の手順で判定を行います。
- 数値の最下位ビットから順に、1ビットずつ値を調べます。
- 調べたビットが1であればセットビットのカウンター(set_count)を、0であれば未セットビットのカウンター(unset_count)をそれぞれインクリメントします。
- すべてのビットを確認した後、両方のカウンターが一致していればtrueを、一致していなければfalseを返します。
C++での実装例
#include <iostream>
using namespace std;
bool hasSameSetUnset(int n) {
int set_count = 0, unset_count = 0;
while(n){
if((n & 1) == 1){
set_count++;
}else{
unset_count++;
}
n = n >> 1; //右へ1ビットシフト
}
if(set_count == unset_count)
return true;
return false;
}
int main() {
int num = 35; //100011
if(hasSameSetUnset(num)){
cout << "Has same set, unset bits";
}else{
cout << "Not same number of set, unset bits";
}
}実行結果
Has same set, unset bits
コードの解説
サンプルコードでは、数値35(2進数で「100011」)をチェックしています。「100011」には1が3つ、0が3つ含まれているため、両者の数が一致していると判定され、「Has same set, unset bits(同じ数のセットビット・未セットビットを持っている)」というメッセージが出力されます。
ビットの判定にはn & 1(AND演算によって最下位ビットだけを取り出す)を使用し、次のビットへ移動する際にはn >> 1(右シフト演算)を使用しています。whileループは数値が0になるまで繰り返されるため、全体の計算量は数値のビット長に比例するO(log n)となり、非常に効率的な処理です。
-
C++でセットビット数に基づいて配列をソートする方法
今回は、配列を「セットビット」の数に基づいてソートするという興味深い問題を取り上げます。セットビットとは、数値を2進数で表したときに「1」となっているビットのことです。セットビット数が多い要素ほど、少ない要素よりも前に配置されるように並べ替えます。例として、12・15・7 という3つの数値を考えてみましょう。それぞれの2進数表現とセットビット数は次のとおりです。1100 (12) → セットビット数 21111 (15) → セットビット数 40111 (7) → セットビット数 3これをセットビット数の降順でソートすると、結果は以下のようになります。1111, 0111, 1100 (つま
-
Pythonで数値の最初と最後のビットだけがセットされているかを判定する方法
問題の概要ある数値 n が与えられたとき、その2進表現において「最初(最上位)」と「最後(最下位)」の位置にのみビットがセットされている(1になっている)かどうかを判定します。例えば、入力が n = 17 の場合、2進表現は 10001 となり、最初と最後の位置にだけ 1 が存在するため、結果は True になります。解決のアプローチこの問題は、以下の手順で効率的に解くことができます。n が 1 と等しい場合は True を返します(2進表現が「1」のみで、最初と最後の位置が一致しているため)。それ以外の場合は、「n - 1 が 2 のべき乗であるか」を判定します。2のべき乗であれば True