The Edit Distance problem is a classic algorithmic challenge that involves determining the minimum number of operations required to convert one string into another. These operations include insertion, deletion, and substitution of characters. This problem has numerous applications in fields such as bioinformatics, natural language processing, and spell checking.
In this tutorial, we will delve into the Edit Distance problem, explore its dynamic programming solution, and provide real-world code examples. We'll also discuss best practices for implementing and optimizing the algorithm.
Given two strings str1 and str2, find the minimum number of operations required to convert str1 into str2. The allowed operations are:
The Edit Distance problem can be efficiently solved using dynamic programming. The idea is to build a 2D table where each cell (i, j) represents the minimum number of operations required to convert the first i characters of str1 into the first j characters of str2.
dp of size (m+1) x (n+1), where m and n are the lengths of str1 and str2, respectively.str1[i-1] and str2[j-1] are the same, no new operation is needed: dp[i][j] = dp[i-1][j-1].dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1.dp[m][n] will be the minimum edit distance.Below is a Python implementation of the Edit Distance algorithm using dynamic programming:
def min_edit_distance(str1, str2):
m = len(str1)
n = len(str2)
# Create a table to store results of subproblems
dp = [[0] * (n + 1) for _ in range(m + 1)]
# Fill d[][] in bottom up manner
for i in range(m + 1):
for j in range(n + 1):
# If first string is empty, only option is to insert all characters of second string
if i == 0:
dp[i][j] = j # Min. operations = j
# If second string is empty, only option is to remove all characters of first string
elif j == 0:
dp[i][j] = i # Min. operations = i
# If last characters are the same, ignore last char and recur for remaining string
elif str1[i - 1] == str2[j - 1]:
dp[i][j] = dp[i - 1][j - 1]
# If last character is different, consider all possibilities and find minimum
else:
dp[i][j] = 1 + min(dp[i][j - 1], # Insert
dp[i - 1][j], # Remove
dp[i - 1][j - 1]) # Replace
return dp[m][n]
# Example usage
str1 = "kitten"
str2 = "sitting"
print(f"Minimum edit distance between '{str1}' and '{str2}': {min_edit_distance(str1, str2)}")
dp with dimensions (m+1) x (n+1), where m and n are the lengths of str1 and str2.dp[i-1][j-1]). If they don't match, we consider all three possible operations and choose the one with the minimum cost.dp[m][n], which represents the minimum edit distance between the two strings.\(O(m \times n)\), where \(m\) and \(n\) are the lengths of the two input strings.\(O(m \times n)\) due to the 2D table used for storing intermediate results.To optimize the space complexity, we can use a 1D array instead of a 2D array. This approach reduces the space usage from \(O(m \times n)\) to \(O(n)\).
Here's an optimized version using a 1D array:
def min_edit_distance_optimized(str1, str2):
m = len(str1)
n = len(str2)
# Create a table to store results of subproblems
dp = [0] * (n + 1)
# Fill d[][] in bottom up manner
for i in range(m + 1):
prev = dp[0]
dp[0] = i
for j in range(1, n + 1):
temp = dp[j]
if str1[i - 1] == str2[j - 1]:
dp[j] = prev
else:
dp[j] = 1 + min(dp[j], # Insert
dp[j - 1], # Remove
prev) # Replace
prev = temp
return dp[n]
# Example usage
str1 = "kitten"
str2 = "sitting"
print(f"Minimum edit distance between '{str1}' and '{str2}': {min_edit_distance_optimized(str1, str2)}")
dp of size \(n+1\) to store the current row's values. The variable prev keeps track of the value from the previous diagonal cell.dp array based on the minimum cost of operations.The Edit Distance problem is a fundamental challenge in computer science with wide-ranging applications. By understanding its dynamic programming solution, you can efficiently compute the minimum number of operations required to transform one string into another. The provided code examples and best practices will help you implement and optimize the algorithm for real-world use cases.