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

C++で大文字・小文字を交互に並べる文字列ソートの実装方法

文字列とは文字の配列です。この問題は、文字列の各要素を「大文字と小文字が交互に現れるように」並べ替えることを目的としています。

問題の概要

「交互 小文字・大文字 文字列ソート」とは、大文字と小文字が混在し、順序がバラバラの文字列が与えられたとき、それを大文字と小文字が交互の位置に配置され、かつそれぞれがソート済みの順序になっている状態に並べ替える問題です。

具体例を見て理解を深めましょう。

入力 : aFegrAfStRzsV
出力 : AaFeRfSgVrstz
説明 :
大文字 : A F R S V
小文字 : a e f g r s t z

大文字と小文字はそれぞれ昇順に整列されているため、あとは両者を交互に組み合わせれば答えが得られます。

問題の内容が理解できたところで、次は解法を考えていきましょう。一つのアプローチとして、大文字用と小文字用にそれぞれソート済みの配列を作成し、最終的な文字列へ交互に配置していくという方法があります。この考え方に基づいたアルゴリズムを以下に示します。

アルゴリズム

ステップ1 : 配列 lowercount[] に、すべての小文字をソート済みの順序で格納する。
ステップ2 : 配列 uppercount[] に、すべての大文字をソート済みの順序で格納する。
ステップ3 : 両方の配列から値を交互に取り出し、最終的な文字列を構築する。
ステップ4 : 結果の配列を出力する。

C++による実装例

#include <iostream>
using namespace std;
#define MAX 26
void alternateULSort(string& s) ;
int main(){
    string str = "aFegrAfStRzsV";
    cout<<"The unsorted string is : "<<str;
    cout<<"\nThe alternate lower upper sorted string is ";
    alternateULSort(str);
    cout << str << "\n";
}
void alternateULSort(string& s){
    int n = s.length();
    int lowerCount[MAX] = { 0 }, upperCount[MAX] = { 0 };
    for (int i = 0; i < n; i++) {
        if (isupper(s[i]))
            upperCount[s[i] - 'A']++;
        else
            lowerCount[s[i] - 'a']++;
    }
    int i = 0, j = 0, k = 0;
    while (k < n) {
        while (i < MAX && upperCount[i] == 0)
            i++;
        if (i < MAX) {
            s[k++] = 'A' + i;
            upperCount[i]--;
        }
        while (j < MAX && lowerCount[j] == 0)
            j++;
        if (j < MAX) {
            s[k++] = 'a' + j;
            lowerCount[j]--;
        }
    }
}

実行結果

The unsorted string is : aFegrAfStRzsV
The alternate lower upper sorted string is AaFeRfSgVrstz

計算量のポイント

この実装ではカウントソートの考え方を応用しています。各文字の出現回数を長さ26の固定サイズ配列に記録するため、時間計算量は O(n)、追加で必要なメモリも定数サイズ(O(1))に抑えられます。比較ベースの一般的なソート(O(n log n))よりも高速に動作する点が大きな特徴です。

  1. C++で行列の上三角と下三角を入れ替える方法

    このチュートリアルでは、C++のコードを使って3×3の正方行列(対角配列)の上三角部分を下三角部分と入れ替える方法を解説します。この操作は、いわゆる「行列の転置」と同じ処理であり、対角配列を入力として与えたとき、期待される結果は以下のようになります。具体的な手順は、以下のアルゴリズムにまとめられます。アルゴリズムステップ1:対角配列を入力する ステップ2:Swap()メソッドに渡す ステップ3:外側のループを3回まで繰り返す ステップ4:内側のループで j = i + 1 から3まで増加させる ステップ5:配列の値を一時変数tempに退避させる ステップ6:arr[i][j] = arr[j]

  2. C++で文字列をトークン化(分割)する2つの方法を解説

    文字列のトークン化(分割)とは、1つの文字列を区切り文字(スペースやカンマなど)を基準に、複数の部分文字列へ分割する処理のことです。C++では、標準ライブラリだけでもいくつかの方法で実現できます。本記事では、代表的な2つの方法をサンプルコード付きで紹介します。方法1:stringstreamを使って空白で分割する1つ目の方法は、stringstreamを使ってスペースで区切られた単語を順に読み取る方法です。この方法はやや制限がありますが、適切なチェックを加えれば十分に目的を果たすことができます。サンプルコード#include <vector> #include <string