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

C++で1回のスワップ操作により次に大きい数を求めるアルゴリズム

ある数 n が与えられたとき、その桁のうち任意の2桁を入れ替える(スワップする)ことで、元の数 n よりも大きい数を作ることを考えます。もし作ることができない場合は -1 を出力します。具体的な例を見てみましょう。

入力例:

12345

出力例:

12354

この例では、4と5の2桁を入れ替えることで、たった1回のスワップ操作でより大きい数を得ています。

アルゴリズムの考え方

  • 数の各桁が降順(大きい順)に並んでいる場合、どの2桁を入れ替えてもより大きい数は作れないため、-1 を返します。
  • 右側から走査し、末尾の桁よりも小さい値を持つ桁のインデックスを探します。
  • 次に、見つかった桁よりも大きく、かつ候補の中で最小となる桁のインデックスを探します。
  • これら2つの桁を入れ替えた結果を新しい数として返します。

C++での実装例

以下は、上記のアルゴリズムをC++で実装したコードです。

#include <bits/stdc++.h>
using namespace std;
string getNextHigherNumber(string num) {
    int len = num.size();
    int firstDigitIndex = -1;
    for (int i = len - 2; i >= 0; i--) {
        if (num[i] < num[len - 1]) {
            firstDigitIndex = i;
            break;
        }
    }
    if (firstDigitIndex == -1) {
        return "-1";
    }
    int secondDigitIndex = -1;
    for (int i = len - 1; i > firstDigitIndex; i--) {
        if (num[i] > num[firstDigitIndex]) {
            if (secondDigitIndex == -1 || num[i] <= num[secondDigitIndex]) {
                secondDigitIndex = i;
            }
        }
    }
    char temp = num[firstDigitIndex];
    num[firstDigitIndex] = num[secondDigitIndex];
    num[secondDigitIndex] = temp;
    return num;
}

int main() {
    string num = "12345";
    cout << "Given number: " << num << endl;
    cout << "Next higher number: " << getNextHigherNumber(num) << endl;
    return 0;
}

実行結果

上記のコードを実行すると、以下のような出力が得られます。

Given number: 12345
Next higher number: 12354

このように、末尾から条件に合う桁を見つけて適切な相手と入れ替えることで、効率的に「次に大きい数」を求めることができます。計算量は文字列の長さに対して線形時間 O(n) で済むため、大きな数値でも高速に処理できるのが特徴です。

  1. C++で軸の片側に点を集めるために削除すべき点の最小数を求める方法

    問題の概要デカルト平面上に N 個の点が与えられます。いくつかの点を削除して、残ったすべての点が「任意のひとつの軸の片側」に収まるようにしたいとき、削除が必要な点の数の最小値を求めるのが本問題の目的です。たとえば、入力が {(10, 5), (-2, -5), (13, 8), (-14, 7)} だったとします。ここで (-2, -5) を削除すれば、残りの点はすべて X 軸より上側に位置することになります。したがって、この場合の答えは 1 となります。アルゴリズム考え方はとてもシンプルです。点を軸の片側に集めたいなら、「反対側にある点をすべて取り除けばよい」からです。具体的には次の手順で解

  2. C++で整数の1の補数(nビット)を求める方法

    1の補数とは本記事では、整数の「1の補数」を求める方法について解説します。C++には補数演算子(~)が用意されており、これを使えば非常に高速に補数を計算できます。ただし、この演算子は32ビット(4バイト)全体に対して補数を求めてしまうため、ここでは「与えられた数値のビット数分だけの補数」を取得する方法を考えます。例として、22という数値を取り上げます。22の2進表現は「10110」であり、その1の補数は「01001」、つまり10進数の9になります。では、この値はどのようにして求めればよいのでしょうか。求め方の手順まず、対象の数値のビット数を求めます。この値をcとします(22の場合、c = 5)