Pythonで文字列内の各文字の出現頻度が、別の文字列の同じ文字の頻度の倍数または約数になっているかを判定する方法
2つの文字列 s と t が与えられたとき、s 内の各文字の出現回数が、t 内の同じ文字の出現回数の「倍数」または「約数(因数)」になっているかどうかを判定する問題を考えてみましょう。
問題の例
たとえば、入力が s = "xxyzzw"、t = "yyyxxxxzz" の場合、出力は True になります。その理由を見てみましょう。
x: s では 2 回、t では 4 回出現 → 4 は 2 の倍数なので条件を満たすy: s では 1 回、t では 3 回出現 → 3 は 1 の倍数なので条件を満たすz: s でも t でも同じ回数出現 → 倍数・約数の関係にあるので条件を満たすw: s には 1 回あるが、t には存在しない → 比較対象がないためスキップされる
このようにすべての文字が条件を満たすため、結果は True となります。
解決のアプローチ
この問題は、以下の手順で解くことができます。
- s_freq := 文字列 s に含まれるすべての文字とその出現頻度を格納したマップを作成する
- t_freq := 文字列 t に含まれるすべての文字とその出現頻度を格納したマップを作成する
- s_freq 内の各文字 ch について次を繰り返す
- ch が t_freq に存在しない場合は、次の反復へ進む
- t_freq[ch] が s_freq[ch] で割り切れる、または s_freq[ch] が t_freq[ch] で割り切れる場合は、次の反復へ進む
- それ以外の場合は False を返す
- すべてのチェックを通過したら True を返す
実装例
理解を深めるために、以下のPythonコードを実装してみましょう。
from collections import defaultdict
def solve(s, t):
s_freq = defaultdict(int)
t_freq = defaultdict(int)
for i in range(0, len(s)):
s_freq[s[i]] += 1
for i in range(0, len(t)):
t_freq[t[i]] += 1
for ch in s_freq:
if ch not in t_freq:
continue
if t_freq[ch] % s_freq[ch] == 0 or s_freq[ch] % t_freq[ch] == 0:
continue
else:
return False
return True
s = "xxyzzw"
t = "yyyxxxxzz"
print(solve(s, t))入力
"xxyzzw", "yyyxxxxzz"
出力
True
補足:より簡潔な書き方
Pythonでは collections.Counter を使うことで、頻度マップの作成を1行で行うこともできます。
from collections import Counter
def solve(s, t):
s_freq = Counter(s)
t_freq = Counter(t)
for ch, cnt in s_freq.items():
if ch not in t_freq:
continue
if t_freq[ch] % cnt != 0 and cnt % t_freq[ch] != 0:
return False
return Trueこの実装では、割り切れない場合のみ False を返し、それ以外は最終的に True を返すというロジックを、より読みやすく表現しています。
-
PythonでDFAを使って2進数文字列が3の倍数かどうかを判定する方法
はじめに ある数の2進表現を配列 n として受け取り、その値が3で割り切れるかどうかを「決定性有限オートマトン(DFA)」を使って判定する問題を考えてみましょう。 例えば、入力が n = [1, 1, 0, 0](10進数の12に相当)であれば、12は3の倍数なので出力は True になります。 DFAによるアプローチ この問題は、次のようなDFAを構築することで解けます。 考え方はシンプルです。ある数が3で割り切れるとき余りは0になり、割り切れない場合は余りが1または2になります。そこで、これら3つの余り(0・1・2)に対応する3つの状態を用意します。初期状態は余り0を表すため、同時に受理
-
Pythonで文字列内の文字がアルファベットかどうかを判定する方法
Pythonでは、文字列クラス(str)が持つ isalpha() メソッドを使うことで、文字列がアルファベットのみで構成されているかどうかを簡単に確認できます。このメソッドは、単一の文字がアルファベットかどうかの判定にも利用できます。 特定の位置の文字がアルファベットかどうかを確認する たとえば、文字列の5番目の文字(インデックス4)がアルファベットかどうかを調べたい場合は、次のように記述します。 >>> s = Hello people >>> s[4].isalpha() True 文字列全体がアルファベットのみかどうかを確認する isalpha()