Skip to content

Refactor bottom-up edit distance function to be class method #7347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
afd78da
Refactor bottom-up function to be class method
tianyizheng02 Oct 17, 2022
f4eeecc
Add type hints
tianyizheng02 Oct 17, 2022
ceea9e5
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 17, 2022
167e5ab
Update convolve function namespace
tianyizheng02 Oct 17, 2022
fc87168
Merge branch 'TheAlgorithms:master' into horn-schunck
tianyizheng02 Oct 17, 2022
b705de4
Merge branch 'TheAlgorithms:master' into horn-schunck
tianyizheng02 Oct 18, 2022
6bd4c52
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 18, 2022
ca7d15b
Merge pull request #1 from tianyizheng02/horn-schunck
tianyizheng02 Oct 18, 2022
5386e57
Remove depreciated np.float
tianyizheng02 Oct 18, 2022
05ba8b4
Merge branch 'TheAlgorithms:master' into decision-tree
tianyizheng02 Oct 18, 2022
67cabe3
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 18, 2022
43004d4
Merge pull request #2 from tianyizheng02/decision-tree
tianyizheng02 Oct 18, 2022
0f91598
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 18, 2022
3a4d643
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 19, 2022
cdb6991
updating DIRECTORY.md
Oct 19, 2022
9f43720
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 19, 2022
c1a8506
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 20, 2022
7876108
updating DIRECTORY.md
Oct 20, 2022
6fb21e9
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 21, 2022
15594ff
updating DIRECTORY.md
Oct 21, 2022
42b4b0f
Merge branch 'TheAlgorithms:master' into master
tianyizheng02 Oct 22, 2022
46b7978
updating DIRECTORY.md
Oct 22, 2022
466dc4e
Renamed function for consistency
ChrisO345 Oct 31, 2022
bda43b3
Merge branch 'master' into master
ChrisO345 Oct 31, 2022
eed1195
updating DIRECTORY.md
Oct 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@
* [Line Length](maths/line_length.py)
* [Lucas Lehmer Primality Test](maths/lucas_lehmer_primality_test.py)
* [Lucas Series](maths/lucas_series.py)
* [Maclaurin Sin](maths/maclaurin_sin.py)
* [Maclaurin Series](maths/maclaurin_series.py)
* [Matrix Exponentiation](maths/matrix_exponentiation.py)
* [Max Sum Sliding Window](maths/max_sum_sliding_window.py)
* [Median Of Two Arrays](maths/median_of_two_arrays.py)
Expand Down
134 changes: 66 additions & 68 deletions dynamic_programming/edit_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,74 +19,72 @@ class EditDistance:
"""

def __init__(self):
self.__prepare__()

def __prepare__(self, n=0, m=0):
self.dp = [[-1 for y in range(0, m)] for x in range(0, n)]

def __solve_dp(self, x, y):
if x == -1:
return y + 1
elif y == -1:
return x + 1
elif self.dp[x][y] > -1:
return self.dp[x][y]
self.word1 = ""
self.word2 = ""
self.dp = []

def __min_dist_top_down_dp(self, m: int, n: int) -> int:
if m == -1:
return n + 1
elif n == -1:
return m + 1
elif self.dp[m][n] > -1:
return self.dp[m][n]
else:
if self.a[x] == self.b[y]:
self.dp[x][y] = self.__solve_dp(x - 1, y - 1)
if self.word1[m] == self.word2[n]:
self.dp[m][n] = self.__min_dist_top_down_dp(m - 1, n - 1)
else:
self.dp[x][y] = 1 + min(
self.__solve_dp(x, y - 1),
self.__solve_dp(x - 1, y),
self.__solve_dp(x - 1, y - 1),
)

return self.dp[x][y]

def solve(self, a, b):
if isinstance(a, bytes):
a = a.decode("ascii")

if isinstance(b, bytes):
b = b.decode("ascii")

self.a = str(a)
self.b = str(b)

self.__prepare__(len(a), len(b))

return self.__solve_dp(len(a) - 1, len(b) - 1)


def min_distance_bottom_up(word1: str, word2: str) -> int:
"""
>>> min_distance_bottom_up("intention", "execution")
5
>>> min_distance_bottom_up("intention", "")
9
>>> min_distance_bottom_up("", "")
0
"""
m = len(word1)
n = len(word2)
dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
for i in range(m + 1):
for j in range(n + 1):

if i == 0: # first string is empty
dp[i][j] = j
elif j == 0: # second string is empty
dp[i][j] = i
elif (
word1[i - 1] == word2[j - 1]
): # last character of both substing is equal
dp[i][j] = dp[i - 1][j - 1]
else:
insert = dp[i][j - 1]
delete = dp[i - 1][j]
replace = dp[i - 1][j - 1]
dp[i][j] = 1 + min(insert, delete, replace)
return dp[m][n]
insert = self.__min_dist_top_down_dp(m, n - 1)
delete = self.__min_dist_top_down_dp(m - 1, n)
replace = self.__min_dist_top_down_dp(m - 1, n - 1)
self.dp[m][n] = 1 + min(insert, delete, replace)

return self.dp[m][n]

def min_dist_top_down(self, word1: str, word2: str) -> int:
"""
>>> EditDistance().min_dist_top_down("intention", "execution")
5
>>> EditDistance().min_dist_top_down("intention", "")
9
>>> EditDistance().min_dist_top_down("", "")
0
"""
self.word1 = word1
self.word2 = word2
self.dp = [[-1 for _ in range(len(word2))] for _ in range(len(word1))]

return self.__min_dist_top_down_dp(len(word1) - 1, len(word2) - 1)

def min_distance_bottom_up(self, word1: str, word2: str) -> int:
"""
>>> EditDistance().min_distance_bottom_up("intention", "execution")
5
>>> EditDistance().min_distance_bottom_up("intention", "")
9
>>> EditDistance().min_distance_bottom_up("", "")
0
"""
self.word1 = word1
self.word2 = word2
m = len(word1)
n = len(word2)
self.dp = [[0 for _ in range(n + 1)] for _ in range(m + 1)]

for i in range(m + 1):
for j in range(n + 1):
if i == 0: # first string is empty
self.dp[i][j] = j
elif j == 0: # second string is empty
self.dp[i][j] = i
elif word1[i - 1] == word2[j - 1]: # last characters are equal
self.dp[i][j] = self.dp[i - 1][j - 1]
else:
insert = self.dp[i][j - 1]
delete = self.dp[i - 1][j]
replace = self.dp[i - 1][j - 1]
self.dp[i][j] = 1 + min(insert, delete, replace)
return self.dp[m][n]


if __name__ == "__main__":
Expand All @@ -99,7 +97,7 @@ def min_distance_bottom_up(word1: str, word2: str) -> int:
S2 = input("Enter the second string: ").strip()

print()
print(f"The minimum Edit Distance is: {solver.solve(S1, S2)}")
print(f"The minimum Edit Distance is: {min_distance_bottom_up(S1, S2)}")
print(f"The minimum edit distance is: {solver.min_dist_top_down(S1, S2)}")
print(f"The minimum edit distance is: {solver.min_distance_bottom_up(S1, S2)}")
print()
print("*************** End of Testing Edit Distance DP Algorithm ***************")