Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

Cプログラムで同じ個数の1と0を持つ「次に大きい数」の2進表現を求める方法

ある数 n の2進表現が与えられたとき、「n より大きい数の中で最小のものであり、かつ0と1の個数が元の数と同じである」という条件を満たす数の2進表現を求めることを考えます。例えば、入力が 1011(10進数で11)であれば、出力は 1101(10進数で13)になります。この問題は、順列生成でおなじみの「次の順列(next permutation)」の考え方を応用することで効率よく解くことができます。それでは、具体的なアルゴリズムを見ていきましょう。

アルゴリズム

nextBin(bin) の処理手順は以下の通りです。

Begin
    len := 文字列 bin の長さ
    for i in range len-2, down to 1, do
        if bin[i] が '0' かつ bin[i+1] が '1' ならば
            bin[i] と bin[i+1] を入れ替える
            break
        end if
    done
    if i = 0 ならば変更は不要、return
    otherwise j := i + 2, k := len – 1
    while j < k, do
        if bin[j] が '1' かつ bin[k] が '0' ならば
            bin[j] と bin[k] を入れ替える
            j と k を更新する
        else if bin[i] が '0' ならば
            break
        else
            j を増やす
        end if
    done
    return bin
End

このアルゴリズムでは、まず右側から走査して「0の直後に1が来ている箇所」を探し、その2文字を入れ替えます。これにより数値が確実に大きくなります。その後、入れ替えた位置より右側の部分について、1をできるだけ左へ、0をできるだけ右へ集めることで、条件を満たす最小の数を作り上げます。

実装例

#include <iostream>
using namespace std;
string nextBinary(string bin) {
    int len = bin.size();
    int i;
    for (int i=len-2; i>=1; i--) {
        if (bin[i] == '0' && bin[i+1] == '1') {
            char ch = bin[i];
            bin[i] = bin[i+1];
            bin[i+1] = ch;
            break;
        }
    }
    if (i == 0)
    "No greater number is present";
    int j = i+2, k = len-1;
    while (j < k) {
        if (bin[j] == '1' && bin[k] == '0') {
            char ch = bin[j];
            bin[j] = bin[k];
            bin[k] = ch;
            j++;
            k--;
        }
        else if (bin[i] == '0')
            break;
        else
            j++;
    }
    return bin;
}
int main() {
    string bin = "1011";
    cout << "Binary value of next greater number = " << nextBinary(bin);
}

このコードでは、まず文字列の後方から走査して入れ替えポイントを特定し、続いて残りの部分を両端から調べながら1と0を並べ替えています。これにより、0と1の総数を保ったまま、元の数よりひとつだけ大きい2進数が得られます。

出力

Binary value of next greater number = 1101

入力 1011 に対して、同じく1が3個・0が1個という構成を保ちながら、より大きい最小の数 1101 が出力されていることが確認できます。

  1. 数値の2進表現が回文かどうかを判定するPythonプログラム

    ここでは、Pythonの組み込み関数を活用して、数値の2進表現が回文(パリンドローム)になっているかどうかを判定します。まず bin() 関数で数値を2進数形式の文字列に変換し、次にその文字列を反転させて元の文字列と比較します。両者が一致すれば回文、一致しなければ回文ではないと判断できます。 実行例 Input: 5 Output: palindrome 解説 数値 5 の2進表現は 101 です。 この文字列を反転しても 101 のままなので、元の文字列と一致します。 したがって、5 は回文であると判定されます。 アルゴリズム Palindromenumber(n) /* n は判定対

  2. 【Python】2つの数値の2進表現がアナグラムかどうかを判定するプログラム

    2つの数値が与えられたとき、その2進表現同士がアナグラム(同じ文字を並べ替えたもの)になっているかどうかを判定します。Pythonでは、collectionsモジュールのCounterクラスと辞書の比較を組み合わせることで、この問題をシンプルかつ効率的に解くことができます。 実行例 入力: a = 8, b = 16 出力: Yes 両方の数値の2進表現は、0と1の個数が同一です。 アルゴリズム ステップ1 : 2つの数値を受け取ります。 ステップ2 : bin()関数で各数値を2進数の文字列に変換し、接頭辞「0b」に相当する先頭2文字を取り除きます。 ステップ3 : 2つの2進表現は