Files
troupe-standup/wizard-work/beam/damerau_levenshtein.py
T

50 lines
1.2 KiB
Python

"""Damerau-Levenshtein edit distance (true DL, not OSA)."""
from __future__ import annotations
def damerau_levenshtein(a: str, b: str) -> int:
la, lb = len(a), len(b)
if la == 0:
return lb
if lb == 0:
return la
last = {}
INF = la + lb
d = [[0] * (lb + 2) for _ in range(la + 2)]
d[0][0] = INF
for i in range(1, la + 2):
d[i][0] = INF
d[i][1] = i - 1
for j in range(1, lb + 2):
d[0][j] = INF
d[1][j] = j - 1
for i in range(1, la + 1):
db = 0
for j in range(1, lb + 1):
i1 = last.get(b[j - 1], 0)
j1 = db
cost = 1
if a[i - 1] == b[j - 1]:
cost = 0
db = j
d[i + 1][j + 1] = min(
d[i][j] + cost,
d[i + 1][j] + 1,
d[i][j + 1] + 1,
)
if i1 > 0 and j1 > 0:
d[i + 1][j + 1] = min(
d[i + 1][j + 1],
d[i1][j1] + (i - i1 - 1) + 1 + (j - j1 - 1),
)
last[a[i - 1]] = i
return d[la + 1][lb + 1]
if __name__ == "__main__":
import sys
print(damerau_levenshtein(sys.argv[1], sys.argv[2]))