C++で指定範囲内のセットビットを別の数値にコピーする方法
このチュートリアルでは、ある数値のセットビット(1になっているビット)を、指定された範囲内で別の数値へコピーするC++プログラムについて解説します。
ここでは2つの整数 x と y が与えられます。私たちのタスクは、y の各ビットを確認し、そのビットが指定された範囲 [l, r] 内にあり、かつ1(セット状態)になっている場合に、x の対応するビットも1にセットすることです。最後に、変更後の x の値を出力します。
アルゴリズム
この問題は、ビットマスクを活用することでシンプルかつ効率的に解くことができます。手順は以下の通りです。
- 範囲 l と r が有効な範囲(1〜32)内にあるかどうかを確認します。無効な場合は処理を中断して何も行いません。
- l から r までの各ビット位置 i について、マスク
1 << (i-1)を作成します。 y & maskの結果が非ゼロであれば、yの i 番目のビットがセットされていることを意味するため、x = x | maskというOR演算によってxの同じ位置のビットをセットします。
サンプルコード
#include <bits/stdc++.h>
using namespace std;
// yからxへセットビットをコピーする
void copySetBits(unsigned &x, unsigned y,
unsigned l, unsigned r){
// l と r は 1 以上 32 以下である必要がある
if (l < 1 || r > 32)
return ;
for (int i=l; i<=r; i++){
int mask = 1 << (i-1);
if (y & mask)
x = x | mask;
}
}
int main() {
unsigned x = 10, y = 13, l = 2, r = 3;
copySetBits(x, y, l, r);
cout << "Modified x: " << x;
return 0;
}
出力
Modified x: 14
動作の解説
上記の例では、x = 10(2進数で 1010)、y = 13(2進数で 1101)、コピー対象の範囲は l=2 から r=3 です。
- 2番目のビット:
yの2番目のビットは 0 なので、xは変更されません。 - 3番目のビット:
yの3番目のビットは 1 なので、xの3番目のビットがセットされます。
その結果、x は 1010 から 1110(10進数で14)へと変化します。このように、ビットごとのAND・OR演算を組み合わせることで、特定の範囲のビットだけを選択的にコピーすることが可能になります。
-
C++でセットビット数に基づいて配列をソートする方法
今回は、配列を「セットビット」の数に基づいてソートするという興味深い問題を取り上げます。セットビットとは、数値を2進数で表したときに「1」となっているビットのことです。セットビット数が多い要素ほど、少ない要素よりも前に配置されるように並べ替えます。例として、12・15・7 という3つの数値を考えてみましょう。それぞれの2進数表現とセットビット数は次のとおりです。1100 (12) → セットビット数 21111 (15) → セットビット数 40111 (7) → セットビット数 3これをセットビット数の降順でソートすると、結果は以下のようになります。1111, 0111, 1100 (つま
-
Pythonで指定範囲内のセットビット数をカウントする方法
正の整数を2進数に変換すると、値が「1」になっているビット(セットビット)がいくつか存在します。セットビットとは、2進数表現において1として表されるビットのことです。この記事では、数値を2進数に変換した後、指定した範囲内にあるセットビットの数を取得する方法を2つ紹介します。bin関数とスライスを使う方法以下の例では、まずbin関数を使って数値の2進数表現を取得します。次にスライス操作で「0b」という接頭辞を取り除き、文字列を反転させた上で、指定された範囲(l桁目からr桁目まで)に含まれる「1」の個数をカウントします。サンプルコードdef SetBits_cnt(n, l, r): bi