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))よりも高速に動作する点が大きな特徴です。
-
C++で行列の上三角と下三角を入れ替える方法
このチュートリアルでは、C++のコードを使って3×3の正方行列(対角配列)の上三角部分を下三角部分と入れ替える方法を解説します。この操作は、いわゆる「行列の転置」と同じ処理であり、対角配列を入力として与えたとき、期待される結果は以下のようになります。具体的な手順は、以下のアルゴリズムにまとめられます。アルゴリズムステップ1:対角配列を入力する ステップ2:Swap()メソッドに渡す ステップ3:外側のループを3回まで繰り返す ステップ4:内側のループで j = i + 1 から3まで増加させる ステップ5:配列の値を一時変数tempに退避させる ステップ6:arr[i][j] = arr[j]
-
C++で文字列をトークン化(分割)する2つの方法を解説
文字列のトークン化(分割)とは、1つの文字列を区切り文字(スペースやカンマなど)を基準に、複数の部分文字列へ分割する処理のことです。C++では、標準ライブラリだけでもいくつかの方法で実現できます。本記事では、代表的な2つの方法をサンプルコード付きで紹介します。方法1:stringstreamを使って空白で分割する1つ目の方法は、stringstreamを使ってスペースで区切られた単語を順に読み取る方法です。この方法はやや制限がありますが、適切なチェックを加えれば十分に目的を果たすことができます。サンプルコード#include <vector> #include <string