Pythonで2つの文字列の編集距離がちょうど1であるかを判定する方法
2つの文字列 s と t が与えられたとき、両者の編集距離(エディット距離)がちょうど1であるかどうかを判定する問題を考えてみましょう。
ここでいう「編集距離」とは、一方の文字列をもう一方の文字列に変換するために必要な操作の回数のことです。許容される操作は次の3種類です。
- 1文字を挿入する
- 1文字を削除する
- 1文字を置き換える
例えば、s = "hello"、t = "heillo" の場合、s に「i」を1文字挿入するだけで t にできるため、出力は True になります。
アルゴリズムの考え方
この問題は、2つのポインタを使って両文字列を先頭から同時に走査することで、O(n) の計算量で効率的に解くことができます。手順は以下のとおりです。
- |s の長さ − t の長さ| > 1 の場合は、編集距離が1になることはあり得ないため False を返します。
- 編集回数をカウントする変数 edit_dist_cnt を 0 に初期化し、ポインタ i と j をそれぞれ 0 にします。
- i < len(s) かつ j < len(t) の間、以下を繰り返します。
- s[i] と t[j] が異なる場合:
- すでに edit_dist_cnt が 1 なら、これ以上編集は許されないので False を返します。
- s の方が長ければ i を進め(削除に相当)、t の方が長ければ j を進め(挿入に相当)、同じ長さなら両方進めます(置換に相当)。
- edit_dist_cnt を 1 増やします。
- s[i] と t[j] が一致する場合は、i と j を両方進めます。
- s[i] と t[j] が異なる場合:
- ループ終了後、いずれかのポインタが末尾に達していない場合は、残りの文字分の編集が必要なので edit_dist_cnt を 1 増やします。
- 最後に、edit_dist_cnt が 1 と等しければ True、そうでなければ False を返します。
実装例
それでは、実際のPythonコードを見てみましょう。
def solve(s, t):
if abs(len(s) - len(t)) > 1:
return False
edit_dist_cnt = 0
i = 0
j = 0
while i < len(s) and j < len(t):
if s[i] != t[j]:
if edit_dist_cnt == 1:
return False
if len(s) > len(t):
i += 1
elif len(s) < len(t):
j += 1
else:
i += 1
j += 1
edit_dist_cnt += 1
else:
i += 1
j += 1
if i < len(s) or j < len(t):
edit_dist_cnt += 1
return edit_dist_cnt == 1
s = "hello"
t = "heillo"
print(solve(s, t))
入力
"hello", "heillo"
出力
True
計算量について
このアルゴリズムは各文字列を一度だけ走査するため、時間計算量は O(n)(n は長い方の文字列の長さ)、追加で必要なメモリは O(1) となります。一般的な動的計画法による編集距離計算(O(n×m))と比べて非常に高速であり、「距離がちょうど1かどうか」という限定された条件を判定する場合には最適な手法です。
-
Pythonで二分木の2つのノード間の距離を求めるプログラム
二分木が与えられたとき、その中の2つのノード間の距離を求めることを考えます。グラフの場合と同じように、2つのノードを結ぶ経路上の辺(エッジ)の数を数え、その本数を距離として返します。 二分木のノード構造 木の各ノードは、次のような構造を持っています。 data : <整数値> right : <木の別のノードへのポインタ> left : <木の別のノードへのポインタ> 問題の例 例として、次のような二分木を考えてみましょう。 この木において、ノード「2」とノード「8」の間の距離を求めたいとします。このときの出力は 4 になります。 ノード2からノード8へ至
-
Pythonで2つのリストに共通要素が存在するかを判定する方法【初心者向け解説】
この記事では、ユーザーから入力された2つのリストを受け取り、それらの間に共通する要素が少なくとも1つ存在するかどうかを判定するPythonプログラムを紹介します。判定には、最もシンプルな「走査(トラバーサル)」という手法を使用します。具体的には、1つ目のリストと2つ目のリストを順番にたどりながら、各要素同士を比較していきます。 実行例 入力 : A = [10, 20, 30, 50] B = [90, 80, 30, 10, 3] 出力 : FOUND(共通要素あり) 入力 : A = [10, 20, 30, 50] B = [100, 200, 300,