2017-11-01 07:04:55 +00:00
|
|
|
"""
|
|
|
|
LCS Problem Statement: Given two sequences, find the length of longest subsequence present in both of them.
|
2019-08-19 07:40:36 +00:00
|
|
|
A subsequence is a sequence that appears in the same relative order, but not necessarily continuous.
|
2017-11-01 07:04:55 +00:00
|
|
|
Example:"abc", "abg" are subsequences of "abcdefgh".
|
|
|
|
"""
|
2017-11-25 09:23:50 +00:00
|
|
|
|
|
|
|
|
2019-08-19 07:40:36 +00:00
|
|
|
def longest_common_subsequence(x: str, y: str):
|
|
|
|
"""
|
|
|
|
Finds the longest common subsequence between two strings. Also returns the
|
|
|
|
The subsequence found
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
|
|
|
|
x: str, one of the strings
|
|
|
|
y: str, the other string
|
|
|
|
|
|
|
|
Returns
|
|
|
|
-------
|
|
|
|
L[m][n]: int, the length of the longest subsequence. Also equal to len(seq)
|
|
|
|
Seq: str, the subsequence found
|
|
|
|
|
|
|
|
>>> longest_common_subsequence("programming", "gaming")
|
|
|
|
(6, 'gaming')
|
|
|
|
>>> longest_common_subsequence("physics", "smartphone")
|
|
|
|
(2, 'ph')
|
|
|
|
>>> longest_common_subsequence("computer", "food")
|
|
|
|
(1, 'o')
|
|
|
|
"""
|
2017-11-01 07:04:55 +00:00
|
|
|
# find the length of strings
|
2019-08-19 07:40:36 +00:00
|
|
|
|
|
|
|
assert x is not None
|
|
|
|
assert y is not None
|
|
|
|
|
2017-11-01 07:04:55 +00:00
|
|
|
m = len(x)
|
|
|
|
n = len(y)
|
|
|
|
|
|
|
|
# declaring the array for storing the dp values
|
2019-08-19 07:40:36 +00:00
|
|
|
L = [[0] * (n + 1) for _ in range(m + 1)]
|
|
|
|
|
|
|
|
for i in range(1, m + 1):
|
|
|
|
for j in range(1, n + 1):
|
2019-10-05 05:14:13 +00:00
|
|
|
if x[i - 1] == y[j - 1]:
|
2019-08-19 07:40:36 +00:00
|
|
|
match = 1
|
2017-11-01 07:04:55 +00:00
|
|
|
else:
|
2019-08-19 07:40:36 +00:00
|
|
|
match = 0
|
|
|
|
|
2019-10-05 05:14:13 +00:00
|
|
|
L[i][j] = max(L[i - 1][j], L[i][j - 1], L[i - 1][j - 1] + match)
|
2019-08-19 07:40:36 +00:00
|
|
|
|
|
|
|
seq = ""
|
|
|
|
i, j = m, n
|
2019-08-31 11:40:50 +00:00
|
|
|
while i > 0 and j > 0:
|
2019-08-19 07:40:36 +00:00
|
|
|
if x[i - 1] == y[j - 1]:
|
|
|
|
match = 1
|
|
|
|
else:
|
|
|
|
match = 0
|
|
|
|
|
|
|
|
if L[i][j] == L[i - 1][j - 1] + match:
|
|
|
|
if match == 1:
|
|
|
|
seq = x[i - 1] + seq
|
|
|
|
i -= 1
|
|
|
|
j -= 1
|
|
|
|
elif L[i][j] == L[i - 1][j]:
|
|
|
|
i -= 1
|
|
|
|
else:
|
|
|
|
j -= 1
|
|
|
|
|
2017-11-01 07:04:55 +00:00
|
|
|
return L[m][n], seq
|
|
|
|
|
2019-08-19 07:40:36 +00:00
|
|
|
|
2019-10-05 05:14:13 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
a = "AGGTAB"
|
|
|
|
b = "GXTXAYB"
|
2019-08-19 07:40:36 +00:00
|
|
|
expected_ln = 4
|
|
|
|
expected_subseq = "GTAB"
|
|
|
|
|
|
|
|
ln, subseq = longest_common_subsequence(a, b)
|
|
|
|
assert expected_ln == ln
|
|
|
|
assert expected_subseq == subseq
|
|
|
|
print("len =", ln, ", sub-sequence =", subseq)
|