文字の置き換えで文字列を別の文字列に変換できるか判定するプログラム(C++実装)
問題の概要
2つの小文字のみで構成された文字列 s と t が与えられているとします。ここで、「s 内に現れる特定の文字をすべて別の文字へ置き換える」という操作を考えます。この操作は何度でも繰り返し実行できるものとし、s を t に変換できるかどうかを判定するのが目的です。
例えば、入力が s = "eye"、t = "pip" の場合、出力は True となります。「e」をすべて「p」に置き換え、その後「y」を「i」に置き換えることで変換できるからです。
解法のアプローチ
この問題は、文字ごとの対応関係(マッピング)をハッシュマップに記録しながら文字列を走査することで解決できます。s の各文字が t のどの文字に対応するかを管理し、矛盾が生じた時点で変換不可能と判断します。
具体的な手順は以下の通りです。
- マップ m1 と m2 を定義する
- n を文字列 s の長さとする
- i を 0 で初期化し、i < n の間、i を 1 ずつ増やしながら以下を繰り返す
- s[i] が m1 に存在する場合
- m1[s[i]] が t[i] と一致していれば、次の反復へ進む
- 一致していなければ、false を返す
- 存在しない場合は、m1[s[i]] に t[i] を登録する
- s[i] が m1 に存在する場合
- ループが最後まで完了すれば true を返す
C++ による実装例
理解を深めるために、以下の実装を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
bool solve(string s, string t) {
map<char, char> m1, m2;
int n = s.size();
for(int i = 0; i < n; i++){
if(m1.count(s[i])){
if(m1[s[i]] == t[i]) continue;
return false;
}
else{
m1[s[i]] = t[i];
}
}
return true;
}
int main(){
string s = "eye", t = "pip";
cout << solve(s, t);
}
入力
"eye","pip"
出力
1
計算量とまとめ
このアルゴリズムは文字列を一度だけ走査するため、文字列の長さを n とすると時間計算量は O(n) となります。また、マップが保持するキーはアルファベットの種類に限られるため、空間計算量は実質 O(1) と非常に効率的です。対応関係の矛盾を即座に検出できるこの手法は、文字列の同型性判定の基本的なアプローチとして広く知られています。
-
Pythonで文字列のすべての文字を使ってk個の回文を作成できるかどうかを判定する方法
問題概要 文字列 s と整数 k が与えられたとき、s に含まれるすべての文字を使って、ちょうど k 個の回文(前から読んでも後ろから読んでも同じになる文字列)を作成できるかどうかを判定します。 たとえば、入力が s = amledavmel、k = 2 の場合、「level」と「madam」という2つの回文を作成できるため、出力は True になります。 解法の考え方 回文の性質に注目すると、この問題は非常にシンプルに解けます。回文では、奇数回出現できる文字は最大で1種類だけです。したがって、文字列のすべての文字を k 個の回文に振り分けられる条件は、「奇数回出現する文字の種類数が k 以
-
Pythonで文字列がパングラムかどうかを判定するプログラムの書き方
パングラム(pangram)とは、英語のアルファベット26文字すべてが少なくとも1回は登場する文章のことです。本記事では、Pythonを使って、与えられた文字列 s がパングラムであるかどうかを判定するプログラムの実装方法を解説します。問題の概要ある文字列 s が文を表しているとします。このとき、英語のアルファベットのすべての文字が少なくとも1回以上使われているかどうかを確認する必要があります。例えば、入力が The grumpy wizards make toxic brew, for the evil queen and Jack の場合、出力は True になります。この文にはアルファベ