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

「trygub」が部分列として現れない文字列を作るC++コード

n個の小文字の英字からなる文字列Sが与えられたとします。このとき、Sの文字を並べ替えて、結果の文字列の中に「trygub」が部分列(subsequence)として含まれないようにする必要があります。

たとえば、入力が S = "pintontrygubabc" の場合、出力は "abbcginnoprttuy" となります。

解法のアプローチ

この問題は驚くほどシンプルで、以下の手順だけで解決できます。

  • 文字列Sを昇順(アルファベット順)にソートする
  • ソートした結果をそのまま返す

なぜソートするだけで良いのか?

文字列を昇順にソートすると、すべての「b」が先頭側に集まり、「t」「r」「y」「g」「u」はそれより後ろに配置されます。「trygub」が部分列になるには、t → r → y → g → u → b という順序で文字が出現する必要がありますが、ソート後は最後の「b」が必ず他の文字より前に来てしまうため、この順序は絶対に成立しません。したがって、ソートされた文字列は常に条件を満たすことが保証されます。

実装例

それでは、実際のC++による実装を見てみましょう。

#include <bits/stdc++.h>
using namespace std;
string solve(string S){
    sort(S.begin(), S.end());
    return S;
}
int main(){
    string S = "pintontrygubabc";
    cout << solve(S) << endl;
}

入力

"pintontrygubabc"

出力

"abbcginnoprttuy"

このように、標準ライブラリの sort を使うことで、計算量 O(n log n) で簡単に問題を解くことができます。特別なデータ構造や複雑なロジックは一切不要です。

  1. C++で、ある文字列の部分列のうち別の文字列の部分文字列となる最長のものの長さを求める

    問題の概要2つの文字列XとYが与えられたとき、Xの部分列のうち、Yの部分文字列(連続する一部分)として現れるものの中で最も長いものの長さを求めます。例えば、X = ABCD、Y = BACDBDCD の場合、出力は 3 になります。これは「ACD」がXの部分列であり、同時にYの部分文字列でもある最長の文字列だからです。動的計画法によるアプローチこの問題は動的計画法(DP)を使うことで効率的に解けます。Xの長さをn、Yの長さをmとすると、(m+1)×(n+1) のサイズのDPテーブルを作成します。DP[i][j] は「X[0…j] の部分列のうち、Y[0…i] の部分文字列となっているものの最大

  2. 【C++】復号化した文字列からk番目の文字を取得する方法

    問題の概要エンコードされた文字列を考えてみましょう。この形式では、部分文字列の繰り返しが「部分文字列 + 繰り返し回数」で表現されます。たとえば、ab2cd2 という文字列は ababcdcd を意味します。ここで k = 4 が与えられた場合、復号化後の文字列の4番目の文字、つまり b を返すことになります。解法のアプローチこの問題は、以下の手順で解くことができます。まず空の復号化用文字列を用意します。元の文字列を先頭から読み込み、英小文字が続く限り部分文字列として抽出します。続いて数字が続く限り読み取り、繰り返し回数として記録します(複数桁の数値にも対応)。抽出した部分文字列を、記録した回