C++で2進数の交互ビットを判定するアルゴリズム
正の整数が与えられたとき、それが交互ビット(alternating bits)を持つかどうかを判定することを考えます。つまり、2進表現において隣り合うどの2つのビットも、必ず異なる値になっている状態です。
例えば、入力が「10」の場合、10の2進表現は「1010」であり、1と0が交互に並んでいるため、出力は True となります。
解法のアプローチ
この問題は、ビット演算を用いて下位ビットから順番に確認していくことで解決できます。手順は以下の通りです。
- p := n AND 1(n の最下位ビットを p に保存する)
- n < 2 の場合は true を返す(1桁のビットは自動的に条件を満たすため)
- n := n / 2(ビットを右に1つシフトする)
- n が 0 になるまで以下を繰り返す:
- c := n AND 1(現在の最下位ビットを取得する)
- c XOR p の結果が 0 の場合、false を返す(同じビットが連続していることを意味する)
- p := c(比較用のビットを更新する)
- n := n / 2(右に1つシフトする)
- ループを抜けたら true を返す
このアルゴリズムでは、XOR 演算を活用しています。隣接する2つのビットが異なれば XOR の結果は 1 になり、同じであれば 0 になるため、結果が 0 になった時点で交互ビットではないと判断できます。計算量は O(log n) と効率的です。
それでは、理解を深めるために実際の実装を見てみましょう。
実装例(C++)
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool hasAlternatingBits(int n) {
bool p = n & 1;
bool c;
if(n < 2)
return true;
n >>= 1;
while(n){
c = n & 1;
if(c ^ p == 0)
return false;
p = c;
n >>= 1;
}
return true;
}
};
main(){
Solution ob;
cout << (ob.hasAlternatingBits(10));
}
入力
10
出力
1
出力が「1」、つまり True を返しており、10(2進数で1010)が交互ビットを持つことが確認できました。
-
C++で数値を2進数表現に変換する方法【再帰処理を解説】
2進数(バイナリ数)とは、0と1という2つの数字のみで構成される数値表現のことです。例えば、01010111 のような形で表されます。コンピュータの内部では、すべてのデータがこの2進数として扱われています。 ある数値を2進数形式で表現する方法はいくつかあります。本記事では、代表的な「再帰を使った方法」を中心に解説します。 再帰を用いた方法 この方法では、再帰呼び出しを利用して数値を2進数形式で表現します。数値を2で割り続けながら、その余りを順に出力していくことで、2進数表現を得ることができます。 アルゴリズム ステップ1: 数値が1より大きい場合、ステップ2とステップ3を実行します。 ステップ
-
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