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

Pythonで文字列をk行のジグザグパターンに変換するプログラムを解説

文字列 s と整数 k が与えられたとき、s の各文字を順に取り出し、左上から右下へ斜めに進んで k 行目に達したら、今度は右上へ折り返す――この動きを繰り返してできる「ジグザグ型」の文字列を作成する方法を解説します。

たとえば、入力が s = "ilovepythonprogramming"k = 5 の場合、出力は次のようになります。

Pythonで文字列をk行のジグザグパターンに変換するプログラムを解説

解法のアプローチ

この問題は、いわゆる「蛇行(ジグザグ)パターン」への文字列変換です。各行にどの文字がどの位置に来るかを記録しておき、最後に行単位で組み立てるのがポイントです。具体的には、次の手順で解きます。

  • 初期化:各行の文字情報を格納する辞書 line を用意し、現在の行番号 cnt を 0、移動方向 delta を 1(下向き)に設定します。
  • 文字の割り当て:文字列 s の各インデックス i と文字 c について、ペア (c, i)line[cnt] の末尾に追加します。
  • 方向の反転:cntdelta を加算しながら進み、cntk に達したら方向を反転(delta = -1)して cntk - 2 に戻します。逆に cnt が 0 になったら、再び下向き(delta = 1)に切り替えます。
  • 結果の組み立て:辞書 line の各行について、元の文字列と同じ長さの空白文字リスト prefix を作成し、記録しておいた位置 y に文字 x を埋め込みます。その後、リストの要素を連結して 1 行分の文字列にし、ans に追加します。
  • 出力:ans の各行を改行文字で連結した文字列を返します。

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

実装例

from collections import defaultdict

class Solution:
    def solve(self, s, k):
        line = defaultdict(list)
        cnt = 0
        delta = 1
        for i, c in enumerate(s):
            line[cnt].append((c, i))
            cnt += delta
            if cnt == k:
                delta = -1
                cnt = k - 2
            if cnt == 0:
                delta = 1

        ans = []

        for i, c in line.items():
            prefix = [" "] * (len(s))
            for x, y in c:
                prefix[y] = x
            ans.append("".join(prefix))

        return "\n".join(ans)

ob = Solution()
s = "ilovepythonprogramming"
k = 5
print(ob.solve(s, k))

入力

"ilovepythonprogramming", 5

出力

Pythonで文字列をk行のジグザグパターンに変換するプログラムを解説

計算量の目安

文字列の長さを n とすると、各文字を一度ずつ処理するため時間計算量は O(n) です。一方、行ごとの結果を保持するために O(n × k) のメモリを使用します。k が極端に大きくない限り、十分に高速に動作するシンプルで効率的なアルゴリズムです。

  1. 【初心者向け】Pythonのcasefold()メソッドで大文字小文字を無視した文字列比較を行う方法

    このチュートリアルでは、Pythonの文字列メソッドstr.casefold()について詳しく解説します。このメソッドは引数を一切受け取らず、戻り値として「大文字小文字を区別しない比較(ケースレス比較)」に適した文字列を返します。 casefold()とは何か? そもそも「ケースレス比較(caseless comparison)」とは何でしょうか。例えば、ドイツ語の小文字ß(エスツェット)は、ssと等価な文字として扱われます。str.casefold()メソッドを使うと、ßがssに変換されます。つまり、casefold()はすべての文字を小文字に変換するだけでなく、こうした特殊な文字の等価変換

  2. Pythonで16進数の文字列を10進数に変換する方法を解説

    この記事では、16進数の文字列を10進数に変換する問題の解決策について詳しく解説します。課題の概要16進数形式の文字列が与えられたとき、それを対応する10進数の値に変換することを目標とします。例えば、16進数の「F」は10進数では「15」に相当します。この問題には主に2つのアプローチがあります。力ずく(ブルートフォース)な手法:int関数を使った明示的な型変換組み込みモジュールを活用する手法:astモジュールのliteral_eval関数を使用方法1:int関数を使った変換最もシンプルで一般的な方法は、Pythonの組み込み関数であるint()を利用するものです。この関数は2つの引数を受け取り