From 9a8287d66b4eeb8e7ff05c3cadaf5402ecf20853 Mon Sep 17 00:00:00 2001 From: s-sanyal Date: Sun, 6 Oct 2019 00:51:47 +0530 Subject: [PATCH 1/2] Added Longest Common Subsequence Algorithm --- pygorithm/dynamic_programming/lcs.py | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 pygorithm/dynamic_programming/lcs.py diff --git a/pygorithm/dynamic_programming/lcs.py b/pygorithm/dynamic_programming/lcs.py new file mode 100644 index 0000000..cdbba95 --- /dev/null +++ b/pygorithm/dynamic_programming/lcs.py @@ -0,0 +1,48 @@ +""" +A subsequence is a sequence that can be derived from another +sequence by deleting some or no elements without changing the +order of the remaining elements. + +For example, 'abd' is a subsequence of 'abcd' whereas 'adc' is not + +Given 2 strings containing lowercase english alphabets, find the length +of the Longest Common Subsequence (L.C.S.). + +Example: + Input: 'abcdgh' + 'aedfhr' + Output: 3 + + Explanation: The longest subsequence common to both the string is "adh" + +Time Complexity : O(M*N) +Space Complexity : O(M*N), where M and N are the lengths of the 1st and 2nd string +respectively. + +""" + + +def longest_common_subsequence(s1, s2): + """ + :param s1: string + :param s2: string + :return: int + """ + m = len(s1) + n = len(s2) + + dp = [[0] * (n + 1) for i in range(m + 1)] + """ + dp[i][j] : contains length of LCS of s1[0..i-1] and s2[0..j-1] + """ + + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + dp[i][j] = 0 + elif s1[i - 1] == s2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + 1 + else: + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + + return dp[m][n] From 0036a4523e43c497925c93d29fea4219cc5e4116 Mon Sep 17 00:00:00 2001 From: S-Sanyal Date: Sun, 4 Oct 2020 22:44:22 +0530 Subject: [PATCH 2/2] Added Edit Distance Algorithm --- .../dynamic_programming/edit_distance.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 pygorithm/dynamic_programming/edit_distance.py diff --git a/pygorithm/dynamic_programming/edit_distance.py b/pygorithm/dynamic_programming/edit_distance.py new file mode 100644 index 0000000..bbdc4d3 --- /dev/null +++ b/pygorithm/dynamic_programming/edit_distance.py @@ -0,0 +1,60 @@ +""" +Given two strings, A and B. Find minimum number of edits required to convert +A to B. Following are the allowed operations(edits) : + +1. Insert(Insert a new character before or after any index i of A) +2. Remove(Remove the charater at the ith index of A) +3. Replace(Replace the character at ith indedx of A to any other character + (possibly same)) + +Cost of all the operations are equal. + +Time Complexity : O(M X N) +Space Complexity : O(M X N), where M and N are the lengths of A and B + respectively. +""" + +def edit_distance(str1, str2): + """ + :param str1: string + :param str2: string + :return: int + """ + m = len(str1) + n = len(str2) + + # Create a table to store results of subproblems + dp = [ [0 for x in range(n + 1)] for x in range(m + 1) ] + + """ + dp[i][j] : contains minimum number of edits to convert str1[0...i] to str2[0...j] + """ + + # 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 second string + elif j == 0: + dp[i][j] = i # Min. operations = i + + # If last characters are 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 are 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] \ No newline at end of file