Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでスタンプ操作により目標文字列を作る手順(インデックス配列)を求めるプログラム

小文字だけで構成された目標の文字列(ターゲット文字列)を作りたいとします。最初の時点では、長さ n の「?」(はてなマーク)だけが並んだシーケンスを持っており、これとは別に小文字からなる「スタンプ」が与えられます。各ターンでは、このスタンプをシーケンス上に重ねて押すことができ、重なった部分の文字がスタンプの対応する文字で置き換わります。使用できるターン数は最大でも 10 × n 回です。

例として、初期シーケンスが "?????"、スタンプが "abc" の場合を考えてみましょう。最初のターンで作れる文字列は "abc??"、"?abc?"、"??abc" のいずれかです。スタンプ操作によってターゲット文字列が作れる場合は、各ターンでスタンプを押した位置(左端の文字のインデックス)を配列として返します。どうしても作れない場合は空の配列を返します。たとえばシーケンスが "ababc"、スタンプが "abc" のとき、答えは [0, 2] になります。"?????" → "abc??" → "ababc" という順に変形できるためです。

入力が s = "abcd"、t = "abcdbcd" の場合、出力は [3, 0] となります。

解法のアプローチ

この問題を解くために、以下の手順に従います。

  • s の長さが 1 の場合:

    • t のすべての文字が s[0] と一致していれば、0 から t の長さまでのインデックスのリストを返し、そうでなければ空のリストを返します。

  • ans := 新しいリスト

  • t が「?」だけで構成されていない間、以下を繰り返します。

    • tmp := t(変更前の状態を保存)

    • i を 0 から s のサイズまで繰り返します。

      • j を s のサイズから i+1 まで逆順に繰り返します。

        • search := i 個の「?」 + s[i:j] の部分文字列 + (s のサイズ − j) 個の「?」 を連結したパターンを作成します。

        • search が t 内に存在する限り、以下を繰り返します。

          • search が見つかった位置を ans の末尾に追加します。

          • t := search を s のサイズ分の「?」で一度だけ置き換えます。

        • t がすべて「?」になったらループを抜けます。

      • t がすべて「?」になったら内側のループも抜けます。

    • tmp と t が同じまま(変化なし)であればループを抜けます。

  • ans を逆順にして返します。

  • 実装例

    理解を深めるために、次の実装を見てみましょう。

    def solve(s, t):
        if len(s) == 1:
            return [i for i in range(len(t))] if all(c == s[0] for c in t) else []
    
        ans = []
        while t != "?" * len(t):
            tmp = t
            for i in range(len(s)):
                for j in reversed(range(i+1, len(s)+1)):
                    search = "?" * i + s[i:j] + "?" * (len(s)-j)
                    while t.find(search) != -1:
                        ans.append(t.find(search))
                        t = t.replace(search, "?"*len(s), 1)
                    if t == "?" * len(t): break
                if t == "?" * len(t): break
            if tmp == t: return []
        return ans[::-1]
    
    s = "abcd"
    t = "abcdbcd"
    print(solve(s, t))

    入力

    "abcd", "abcdbcd"

    出力

    [3, 0]

    1. Pythonでリスト内の最小値を見つける方法を解説

      この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。

    2. Pythonプログラムで数の偶数の約数の合計を求める方法

      この記事では、以下の問題文に対する解決策について詳しく解説します。 問題文:ある数が与えられたとき、その数のすべての偶数の約数(因子)の合計を求めて表示します。 アプローチ まず、与えられた数が奇数であるかどうかを確認します。奇数には偶数の約数が存在しないため、その場合は 0 を返します。 数が偶数である場合は、実際の計算に進みます。ここでのポイントは、20(つまり1)以外のすべての項を掛け合わせることで、偶数の約数の合計が得られるという点です。 偶数の約数からすべての奇数を取り除くために、20 に相当する「1」を無視します。この処理を行うことで、残るのは偶数の約数のみとなります。なお、2 は