I was doing some reading on the Wagner Fischer algorithm algorithm for computing the edit distance on strings. None of the examples in the literature I have read showed how to recover the edit sequences from the final populated matrix. The examples only showed total number of edits.
The logic I am using is simply calling min()
on the 4 x 4 submatrix of matrix L
that ends L[m][n]
until I reach L[0][0]
. It seems like the logic should be to compare the value returned by min()
and compare it to the current L[i][j]
to recover the edit at that position. Then we simply append this to an array that represents the total edit operations and finally reverse the list.
I have tested this code and compared it against the Python Levenshtein module on pypi.org and it looks to be OK. However, I wanted to get some feedback on this methodology of how to output the actual edit sequence. Is there some boundary case I might be missing?
def edit_distance(x, y):
m = len(x)
n = len(y)
L = [ [0] * (n+1) for i in xrange(m+1) ]
for i in range(0, m+1):
L[i][0] = i
for j in range(0, n+1):
L[0][j] = j
for i in range (1, m+1):
for j in range(1, n+1):
if x[i-1] == y[j-1]:
L[i][j] = L[i-1][j-1]
else:
L[i][j] = min(L[i][j-1], L[i-1][j], L[i-1][j-1]) + 1
edits = []
i = m
j = n
while i > 0 and j > 0:
back = min(L[i][j-1], L[i-1][j], L[i-1][j-1])
if back == L[i-1][j-1]:
if back == L[i][j]:
edits.append('NOOP')
elif back == L[i][j] - 1:
edits.append('SUBST')
i -= 1
j -= 1
elif back == L[i][j-1]:
edits.append('INSERT')
j -= 1
elif back == L[i-1][j]:
edits.append('DELETE')
i -= 1
print x
print edits[::-1]
print y