C++で2つの文字列の共通しない文字を検索・抽出する方法
はじめに
本記事では、C++を使用して2つの文字列に共通しない文字(アンコモン・キャラクター)を見つけるプログラムについて解説します。
具体的には、2つの文字列が与えられたとき、どちらか一方の文字列にのみ含まれる文字を抽出し、アルファベット順にソートして出力するのが目的です。
問題の概要
入力として2つの文字列を受け取り、次の条件を満たす文字を出力します。
- 片方の文字列には存在するが、もう片方には存在しない文字
- 出力はアルファベット順(a〜z)にソートされていること
例えば、「tutorials」と「point」という2つの文字列が与えられた場合、共通しない文字は「a l n p r s u」となります。
アルゴリズムの考え方
この問題は、サイズ26の整数型配列を使うことで効率的に解けます。各要素は英小文字(a〜z)に対応し、その文字がどちらの文字列に出現したかを記録します。
- サイズ26の配列
isthereを用意し、すべての要素を0で初期化します。 - 1つ目の文字列を走査し、出現した文字に対応する要素を1に設定します。
- 2つ目の文字列を走査し、すでに値が1または-1の文字(=両方の文字列に共通する文字)は-1に、それ以外の新しい文字は2に設定します。
- 最終的に、値が1(1つ目のみ)または2(2つ目のみ)である文字だけを出力します。-1は両方に共通する文字なので除外されます。
C++での実装例
#include <bits/stdc++.h>
using namespace std;
const int LIMIT_CHAR = 26;
// 共通しない文字を見つける関数
void calculateUncommonCharacters(string str1, string str2) {
int isthere[LIMIT_CHAR];
for (int i = 0; i < LIMIT_CHAR; i++)
isthere[i] = 0;
int l1 = str1.size();
int l2 = str2.size();
// 1つ目の文字列に出現する文字をマーク
for (int i = 0; i < l1; i++)
isthere[str1[i] - 'a'] = 1;
// 2つ目の文字列を走査して分類
for (int i = 0; i < l2; i++) {
if (isthere[str2[i] - 'a'] == 1 || isthere[str2[i] - 'a'] == -1)
isthere[str2[i] - 'a'] = -1; // 両方に共通する文字
else
isthere[str2[i] - 'a'] = 2; // 2つ目のみの文字
}
// 片方にしか存在しない文字を出力
for (int i = 0; i < LIMIT_CHAR; i++)
if (isthere[i] == 1 || isthere[i] == 2)
cout << (char)(i + 'a') << " ";
}
int main() {
string str1 = "tutorials";
string str2 = "point";
calculateUncommonCharacters(str1, str2);
return 0;
}
実行結果
a l n p r s u
コードのポイント
- 計算量: 文字列の長さをNとすると、時間計算量はO(N)、空間計算量はO(1)(固定サイズ26の配列のみ使用)で非常に効率的です。
- 状態管理: 配列の値(0 / 1 / 2 / -1)によって、各文字が「未出現」「1つ目のみ」「2つ目のみ」「両方に共通」のどれに該当するかを一目で判別できます。
- 自動ソート: 配列をインデックス順(aからz)に走査するため、出力は自然とアルファベット順になります。別途ソート処理は不要です。
まとめ
このように、フラグ配列を活用することで、2つの文字列の共通しない文字を線形時間で効率よく求められます。文字列処理における基本的かつ実用的なテクニックなので、ぜひマスターしておきましょう。
-
C++で円柱の周囲長を求める方法
円柱の直径と高さが与えられたとき、その周囲長を求めたいというケースがあります。しかし、周囲長は本来2次元図形の輪郭の長さを表す概念であるため、3次元の物体である円柱に対して直接求めることはできません。そこで考え方として、円柱の断面を展開して長方形として捉える方法を使います。円柱を横から見た断面は長方形になり、この長方形の2辺はそれぞれ「直径」と「高さ」に対応します。つまり、円柱の周囲長は次の式で計算できます。計算式p = (2 * d) + (2 * h)d: 円柱の直径h: 円柱の高さ直径の2倍と高さの2倍を足し合わせることで、展開された長方形の外周が求まります。C++での実装例以下は、直径
-
【C++】2つの文字列を比較して共通しない文字を抽出するプログラム
この記事では、2つの異なる文字列を比較した際に、共通しない文字(どちらか一方にしか存在しない文字)を見つけ出すプログラムについて解説します。 ご存知の通り、文字列とは本質的に文字の配列です。そのため、比較を行う際は、一方の文字列の文字を先頭から順に走査しながら、その文字がもう一方の文字列にも存在するかどうかを確認していきます。 ここで、最初の文字列をA、2番目の文字列をBとすると、まず「A − B」(Aには含まれるがBには含まれない文字)が求められます。同様の手順で「B − A」も計算できます。 この2つの結果を組み合わせると、次の式になります。 ( A − B ) ∪ ( B − A )