C++で文字列に含まれる余分な1文字を効率的に検索する方法
長さが n の文字列 S と、長さが n + 1 の文字列 T があるとします。文字列 T には S に含まれるすべての文字が含まれており、さらに余分な文字が1つだけ追加されています。この記事では、効率的なアルゴリズムを使って、その余分な文字を見つける方法を解説します。
アプローチ:ハッシュマップを活用する
この問題を解くためには、ハッシュマップ(連想配列)を利用するのが効果的です。手順は以下のとおりです。
まず空のハッシュマップを用意し、文字列 T のすべての文字の出現回数をカウントして登録します。次に、文字列 S の各文字についてカウントを1ずつ減らしていきます。すべての処理が終わった時点で、カウントが 1 のまま残っている文字が、まさに余分な文字ということになります。
この方法の計算量は O(n) であり、文字列の長さに比例した時間で処理が完了するため、非常に効率的です。
実装例(C++)
#include<iostream>
#include<unordered_map>
using namespace std;
char getExtraCharacter(string S, string T) {
unordered_map<char, int> char_map;
for (int i = 0; i < T.length(); i++)
char_map[T[i]]++;
for (int i = 0; i < S.length(); i++)
char_map[S[i]]--;
for (auto item = char_map.begin(); item != char_map.end(); item++) {
if (item->second == 1)
return item->first;
}
}
int main() {
string S = "PQRST";
string T = "TUQPRS";
cout << "Extra character: " << getExtraCharacter(S, T);
}実行結果
Extra character: U
コードの解説
このプログラムでは、まず unordered_map を使って文字ごとの出現回数を管理しています。文字列 T の文字をすべて登録した後、文字列 S の文字でカウントを減算します。S と T に共通する文字はカウントが 0 に戻りますが、T にのみ存在する余分な文字はカウントが 1 のまま残ります。最後にその文字を検索して返すことで、余分な文字を特定できます。
なお、この問題は XOR 演算を使う方法でも解くことができます。すべての文字の XOR を取ると、同じ文字は打ち消し合い、余分な1文字だけが残る仕組みです。こちらも O(n) の計算量で動作し、メモリ使用量をさらに抑えられます。
-
C++で文字列の部分文字列の総数を求める方法を解説
この記事では、与えられた文字列から作成できる空でない部分文字列の個数を求める方法について解説します。入力 : string = "moon" 出力 : 10 説明 : 部分文字列は m、o、o、n、mo、oo、on、moo、oon、moon の 10 個です。 入力 : string = "yellow" 出力 : 21解法のアプローチ文字列の長さを n とします。上の例からも分かるように、考えられるすべての部分文字列の個数を求めるには、長さ n、(n-1)、(n-2)、(n-3)、……2、1 の部分文字列の個数を順に加算していく必要があります。部分文
-
C++で括弧文字列からイコールポイント(等分点)を見つける方法
この記事では、C++を使って括弧の文字列からイコールポイント(等分点)を求める方法を解説します。 イコールポイントとは? イコールポイントとは、あるインデックス i において、その位置より前にある開き括弧「(」の数と、その位置以降にある閉じ括弧「)」の数が等しくなる地点のことです。 例として、次の括弧文字列を考えてみましょう。 (()))( ()()() )) ) → 元の文字列は (()))(()()()))) この文字列を詳しく観察すると、インデックス0〜9の範囲に含まれる開き括弧は5個、インデックス9〜14の範囲に含まれる閉じ括弧も5個あります。したがって、インデックス9がこの文字列の