Pythonで特定の文字列を構築する最小コストを求めるプログラム
長さ n の文字列「str」を構築することを考えてみましょう。この文字列を構築するには、次の2種類の操作を使用できます。
- コスト a で、str の末尾に1文字追加する。
- コスト r で、str の末尾に部分文字列 sub_str を追加する。
私たちの課題は、文字列 str を構築するときにかかる最小コストを計算することです。
たとえば、入力が a = 5、r = 4、str = 'tpoint' の場合、出力は 29 になります。
文字列 'tpoint' を構築する際の各ステップのコストは以下のとおりです。
str = 't'; 新しい文字を追加したため、コストは5。 str = 'tp'; 新しい文字を追加したため、コストは5。 str = 'tpo'; 新しい文字を追加したため、コストは5。 str = 'tpoi'; 新しい文字を追加したため、コストは5。 str = 'tpoin'; 新しい文字を追加したため、コストは5。 str = 'tpoint'; 部分文字列 't' を追加したため、コストは4。
合計コストは 5 + 5 + 5 + 5 + 5 + 4 = 29 となります。
解き方のアルゴリズム
この問題を解くために、以下の手順に従います。
- size := str のサイズ(文字数)
- largest := 空のリストを作成
- low := 0
- upp を 1 から size+1 までの範囲でループする:
- str のインデックス low から upp までの部分文字列が、インデックス 0 から low までの範囲内に存在しない間、次を繰り返す:
- low := low + 1
- largest の末尾に (upp − low) を挿入する
- str のインデックス low から upp までの部分文字列が、インデックス 0 から low までの範囲内に存在しない間、次を繰り返す:
- c := a を含む新しいリストを作成
- i を 1 から size までの範囲でループする:
- largest[i] が 0 と等しい場合:
- c の末尾に (c の最後の要素 + a) を挿入する
- それ以外の場合:
- c の末尾に min(c の最後の要素 + a, c[i − largest[i]] + r) を挿入する
- largest[i] が 0 と等しい場合:
- c の最後の要素を返す
考え方のポイント
このアルゴリズムは動的計画法(DP)を利用しています。リスト c の各要素 c[i] は「最初の i+1 文字を構築するのに必要な最小コスト」を表します。各位置において、「新しい文字を1つ追加する(コスト a)」か「これまでに出現した部分文字列を末尾にコピーする(コスト r)」かの、より安い方を選択することで、文字列全体を構築する最小コストを効率よく求められます。
実装例
理解を深めるために、以下の実装を見てみましょう。
def solve(a, r, str):
size = len(str)
largest = []
low = 0
for upp in range(1, size+1):
while str[low:upp] not in str[:low]:
low += 1
largest.append(upp - low)
c = [a]
for i in range(1, size):
if largest[i] == 0:
c.append(c[-1] + a)
else:
c.append(min(c[-1] + a, c[i - largest[i]] + r))
return c[-1]
print(solve(5, 4, 'tpoint'))
入力
5, 4, 'tpoint'
出力
29
-
指定された文字列が母音回文であるかどうかを確認するPythonプログラム
はじめに この記事では、「与えられた文字列から子音をすべて取り除いたとき、残った母音だけの文字列が回文になっているかどうかを判定する」という問題を、Pythonプログラムで解く方法を解説します。 問題の概要 問題文:母音と子音の両方を含む文字列が与えられます。まず文字列からすべての子音を取り除き、その結果得られた文字列が回文(前から読んでも後ろから読んでも同じ並びになる文字列)であるかどうかを確認してください。 解決のアプローチ この問題は、以下の手順で解くことができます。 元の文字列を先頭から順に走査し、母音(a・e・i・o・u)だけを取り出して新しい文字列を作成します。 母音が1つも
-
Pythonで文字列がパングラムかどうかを判定するプログラムの作成方法
本記事では、与えられた文字列がパングラムであるかどうかを判定するPythonプログラムの解法とアプローチについて詳しく解説します。 問題の概要 文字列入力が与えられたとき、その文字列がパングラムであるかどうかを判定するPythonプログラムを作成します。 パングラムとは? パングラムとは、英語のアルファベット26文字すべてを少なくとも1回ずつ含む文章や一連の単語のことです。有名な例として「The quick brown fox jumps over the lazy dog」があります。 解法のアプローチ この問題は、以下の手順で解くことができます。 アルファベット全体を表す基準となる文字列