Pythonでアナグラム単語の最大サブセットサイズを求める方法
小文字からなる単語のリストが与えられたとき、互いにアナグラムの関係にある文字列からなる最大サブセットのサイズを求めるのが本記事の課題です。
アナグラムとは、一方の文字列がもう一方の文字列の並べ替え(文字の順番を入れ替えたもの)になっている関係を指します。たとえば、「python」と「typhon」はアナグラムです。
Pythonでは、標準ライブラリのcollections.Counter()メソッドを活用することで、この問題を非常に効率的に解決できます。
アルゴリズムの手順
ステップ1:スペース区切りの入力文字列を単語ごとに分割する。
ステップ2:リスト内の各文字列を文字順にソートする。
ステップ3:Counterメソッドで辞書を作成し、ソート済み文字列をキー、出現頻度を値として格納する。
ステップ4:max関数を使って頻度の最大値を取得する。
実装コード
# アナグラム単語の最大サブセットのサイズを求める関数
from collections import Counter
def largestana(str1):
# スペース区切りの入力文字列を単語ごとに分割
str1 = str1.split(" ")
# リスト内の各文字列をソートする
for i in range(0, len(str1)):
str1[i] = ''.join(sorted(str1[i]))
# Counterメソッドで辞書を作成
# キー:ソート済み文字列 値:出現頻度
newstr1 = Counter(str1)
# 頻度の最大値を取得して表示
print("アナグラム単語の最大サブセットのサイズ ::>", max(newstr1.values()))
# ドライバープログラム
if __name__ == "__main__":
str1 = input("文字列を入力してください ::>")
largestana(str1)
実行結果
文字列を入力してください ::> qwe ewq rty ytr ytr ytr
アナグラム単語の最大サブセットのサイズ ::> 4
仕組みの解説
このプログラムのポイントは、各単語を文字ごとにソートしている点にあります。アナグラム同士の文字列は、構成する文字がまったく同じであるため、ソートを行うと必ず同一の文字列になります。上記の例では、「qwe」「ewq」はどちらもソートすると「eqw」になり、「rty」「ytr」はすべて「rty」になります。その結果、頻度は「eqw」が2回、「rty」が4回となり、最大値の4が答えとして出力されます。
計算量は、n個の単語それぞれの長さをkとすると O(n・k log k) となり、Counterによる集計は O(n) で処理されるため、実用上十分高速なアルゴリズムです。
-
Pythonでグラフ内の最大クリークの最小サイズを求めるプログラム
問題概要 グラフが与えられたとき、そのグラフに含まれる最大クリークの最小サイズを求める問題を考えます。ここで「クリーク」とは、グラフの頂点部分集合のうち、任意の2つの頂点が必ず隣接している(つまり、すべての頂点ペア間に辺が存在する)ものを指します。 最大クリークを求める問題は多項式時間では解けないことが知られているため(NP困難問題)、小規模なグラフについてノード数とエッジ数が与えられた場合には、工夫したアルゴリズムで最大クリークのサイズを導き出す必要があります。 例えば、入力が nodes = 4、edges = 4 の場合、出力は 2 となります。このグラフでは、クリークの最大サイズは 2
-
Pythonで配列内の最大の要素を見つける方法を解説
この記事では、「配列の中から最大の要素を求める」という問題の解決方法について詳しく解説します。 問題の概要 問題文:与えられた配列に対して、その中で最も大きい要素を計算して求める必要があります。 ここではブルートフォース(総当たり)アプローチを使用します。これは、配列全体を先頭から順番に走査しながら各要素を比較し、その時点での最大値を更新していくというシンプルかつ確実な手法です。 実装例 以下に具体的なコードを示します。 # 最大値を求める関数 def largest(arr, n): # 最大要素の初期値として最初の要素を設定 max = arr[0] # 配列全体を