From a289a4f61d9187746e7f248914415331de337b36 Mon Sep 17 00:00:00 2001 From: Avijit Dey Date: Wed, 11 Oct 2023 17:59:17 +0530 Subject: [PATCH 1/4] implement longest common subsequence --- .../longest_common_subsequence.py | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 pyds_a/algorithms/dynamic programming/longest_common_subsequence.py diff --git a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py new file mode 100644 index 0000000..96e9354 --- /dev/null +++ b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py @@ -0,0 +1,66 @@ +""" +Author: Avijit-Dey + +longest_common_subsequence.py - A Python implementation of Longest Common Subsequence, +a famous problem in Dynamic Programming. + +A longest common subsequence (LCS) is the longest subsequence common to all sequences +in a set of sequences (often just two sequences). It differs from the longest common +substring: unlike substrings, subsequences are not required to occupy consecutive +positions within the original sequences. The problem of computing longest common +subsequences is a classic computer science problem, the basis of data comparison +programs such as the diff utility, and has applications in computational linguistics +and bioinformatics. It is also widely used by revision control systems such as Git for +reconciling multiple changes made to a revision-controlled collection of files. + +Resources used: +--https://en.wikipedia.org/wiki/Longest_common_subsequence + +For doctests run the following command: +python3 -m doctest -v longest_common_subsequence.py (linux/unix) +python -m doctest -v longest_common_subsequence.py (windows) + +For manual testing run: +python3 longest_common_subsequence.py (linux/unix) +python longest_common_subsequence.py (windows) +""" + + +def longest_common_subsequence(X: str, Y: str) -> int: + """ + + Examples: + >>> longest_common_subsequence("AGGTAB", "GXTXAYB") + 4 + >>> longest_common_subsequence("AAAAAA", "GGGGGG") + 0 + >>> longest_common_subsequence("ROFLABU", "DAFLADBU") + 5 + """ + # length of the strings + m = len(X) + n = len(Y) + + # declaring the lookup table list for storing the values + lookup_table = [[0] * (n + 1) for i in range(m + 1)] + + """Following steps build L[m + 1][n + 1] in bottom up fashion + Note: L[i][j] contains length of LCS of X[0..i-1] + and Y[0..j-1]""" + for i in range(m + 1): + for j in range(n + 1): + if i == 0 or j == 0: + lookup_table[i][j] = 0 + elif X[i - 1] == Y[j - 1]: + lookup_table[i][j] = lookup_table[i - 1][j - 1] + 1 + else: + lookup_table[i][j] = max(lookup_table[i - 1][j], lookup_table[i][j - 1]) + + # return the length of the longest common subsequence + return lookup_table[m][n] + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From caf923301ecf874104f75b6433770283f11aa999 Mon Sep 17 00:00:00 2001 From: Avijit Dey Date: Sat, 14 Oct 2023 20:24:09 +0530 Subject: [PATCH 2/4] improve pylint ratings --- .../longest_common_subsequence.py | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py index 96e9354..a16384e 100644 --- a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py +++ b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py @@ -26,7 +26,7 @@ """ -def longest_common_subsequence(X: str, Y: str) -> int: +def longest_common_subsequence(first_string: str, second_string: str) -> int: """ Examples: @@ -38,26 +38,24 @@ def longest_common_subsequence(X: str, Y: str) -> int: 5 """ # length of the strings - m = len(X) - n = len(Y) + len_first_str = len(first_string) + len_secong_str = len(second_string) # declaring the lookup table list for storing the values - lookup_table = [[0] * (n + 1) for i in range(m + 1)] + lookup_table = [[0] * (len_secong_str + 1) for i in range(len_first_str + 1)] - """Following steps build L[m + 1][n + 1] in bottom up fashion - Note: L[i][j] contains length of LCS of X[0..i-1] - and Y[0..j-1]""" - for i in range(m + 1): - for j in range(n + 1): + # Following steps build in bottom up fashion: + for i in range(len_first_str + 1): + for j in range(len_secong_str + 1): if i == 0 or j == 0: lookup_table[i][j] = 0 - elif X[i - 1] == Y[j - 1]: + elif first_string[i - 1] == second_string[j - 1]: lookup_table[i][j] = lookup_table[i - 1][j - 1] + 1 else: lookup_table[i][j] = max(lookup_table[i - 1][j], lookup_table[i][j - 1]) # return the length of the longest common subsequence - return lookup_table[m][n] + return lookup_table[len_first_str][len_secong_str] if __name__ == "__main__": From 42f5cef0e0150318842776a6c9227b475301b30e Mon Sep 17 00:00:00 2001 From: Avijit Dey Date: Sat, 14 Oct 2023 20:32:57 +0530 Subject: [PATCH 3/4] improve pylint ratings --- .../dynamic programming/longest_common_subsequence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py index a16384e..dd80feb 100644 --- a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py +++ b/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py @@ -26,7 +26,7 @@ """ -def longest_common_subsequence(first_string: str, second_string: str) -> int: +def longest_common_subsequence(first_string, second_string): """ Examples: From 44160018bcd6babde0310d2f8bb7a36272aefe20 Mon Sep 17 00:00:00 2001 From: Avijit Dey Date: Mon, 16 Oct 2023 17:13:12 +0530 Subject: [PATCH 4/4] fix the pylint test fail --- .../longest_common_subsequence.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pyds_a/algorithms/{dynamic programming => dynamic_programming}/longest_common_subsequence.py (100%) diff --git a/pyds_a/algorithms/dynamic programming/longest_common_subsequence.py b/pyds_a/algorithms/dynamic_programming/longest_common_subsequence.py similarity index 100% rename from pyds_a/algorithms/dynamic programming/longest_common_subsequence.py rename to pyds_a/algorithms/dynamic_programming/longest_common_subsequence.py