Pythonで文字列内のすべての数字を文字に置き換える方法
問題の概要
小文字の英字と数字が交互に並んだ英数字文字列 s を考えてみましょう。偶数番目の位置には小文字の英字が、奇数番目の位置には数字が含まれています。
ここで、任意の文字 c と数値 x を受け取り、「c の x 番後の文字」を返す操作 shift(c, x) を定義します。たとえば shift('p', 5) = 'u'、shift('a', 0) = 'a' のようになります。
この問題では、すべての奇数インデックス i にある数字 s[i] を shift(s[i-1], s[i]) の結果で置き換え、すべての数字を置き換え終えた後の文字列を求めます。
入力例
s = "a2b1d4f3h2"
出力例
"acbcdhfihj"
この結果は、次のように各数字を直前の文字からシフトすることで得られます。
shift('a', 2) = 'c'shift('b', 1) = 'c'shift('d', 4) = 'h'shift('f', 3) = 'i'shift('h', 2) = 'j'
解き方のアルゴリズム
この問題は、次の手順で解くことができます。
- 結果を格納するための空文字列
resを用意します。 - インデックス
iを 0 から文字列sの長さまで順に走査します。s[i]が数字の場合:resに「直前の文字s[i-1]を、その数字の分だけシフトした文字」(chr(ord(s[i-1]) + int(s[i])))を連結します。- それ以外の場合:
resにs[i]をそのまま連結します。
- 最後に
resを返します。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
def solve(s):
res = ""
for i in range(len(s)):
if s[i].isdigit():
res += chr(int(s[i]) + ord(s[i-1]))
else:
res += s[i]
return res
s = "a2b1d4f3h2"
print(solve(s))
入力
"a2b1d4f3h2"
出力
acbcdhfihj
コードのポイント
- isdigit()メソッド: 文字が数字かどうかを簡単に判定できます。
- ord()関数: 文字をUnicodeコードポイント(ASCIIコード)の整数値に変換します。
- chr()関数: 整数値を対応する文字に変換する、ord()の逆の働きをします。
- 計算量: 文字列を一度だけ走査するため、時間計算量はO(n)と効率的です。
パフォーマンスを向上させる工夫
上記の実装では文字列の連結を繰り返していますが、Pythonでは文字列がイミュータブル(変更不可)なため、連結のたびに新しい文字列オブジェクトが生成されます。文字列が長くなる場合は、リストに要素を追加していき、最後に join() で結合する方法がより高速です。
def solve(s):
res = []
for i, ch in enumerate(s):
if ch.isdigit():
res.append(chr(int(ch) + ord(s[i-1])))
else:
res.append(ch)
return "".join(res)
どちらの実装でも結果は同じですが、大規模なデータを扱う際には後者の書き方が推奨されます。
-
【Python】配列内のすべての桁を使って3で割り切れる数を作成できるか判定する方法
この記事では、与えられた問題文を解決するための解法とアプローチについて詳しく解説します。 問題文 整数の配列が入力として与えられたとき、これらの数値に含まれるすべての桁を使用して、3で割り切れる整数を作成できるかどうかを判定する必要があります。 ここでは、整数の配列と配列の長さという2つの引数を受け取る関数を作成します。 解法のポイント この実装は、暗算でよく使われる数学的な性質に基づいています。それは次の通りです。 「ある数の各桁の合計が3で割り切れるならば、その数自体も3で割り切れる」 この性質を利用すると、実際に桁を組み合わせて数値を生成する必要はなく、配列内の各要素について3で割った余
-
【Python】文字列がすべてユニークな文字で構成されているか判定する方法
本記事では、与えられた文字列に含まれる文字がすべて一意(ユニーク)であるかどうかを判定するPythonプログラムについて、その解法とアプローチをわかりやすく解説します。 問題の概要 文字列が入力として与えられたとき、その文字列に含まれるすべての文字が重複なく一意であるかどうかを判定します。たとえば「abcde」はすべて異なる文字で構成されているためTrue、「tutorialspoint」のように同じ文字が複数回出現する場合はFalseとなります。 アプローチ この問題は、以下のような手順で効率的に解くことができます。 ブール値の配列を用意する: 各インデックス i が「アルファベット(AS