Find the Longest
Common Subsequence of two strings.
Input. Two strings consisting only of lowercase
English letters. The length of each string does not
exceed 1000 characters.
Output. Print the longest common subsequence of two
strings.
Sample
input |
Sample
output |
abacaba dacabc |
acab |
longest common subsequence
The task of this problem is
to find the longest common subsequence (LCS) of two strings and print it.
Construct an array dp, where dp[i][j] represents the length of
the LCS of the substrings x[1…i] and y[1…j]. The value dp[n][m] will correspond to the
length of the LCS of the original strings (|x|
= n, |y| = m).
After computing the dp
array, reconstruct the LCS by performing a reverse traversal of the matrix dp
from cell (n, m) to (0, 0). At each position (i, j), we follow the next
steps:
·
If the characters xi and yj match, this character is part of the LCS.
Add it to the resulting string res, and move diagonally to cell (i – 1, j – 1), continuing to build the
LCS for x[1…i – 1] and y[1…j – 1].
·
If the characters xi
and yj do not match, move to the
cell with the larger value, either (i, j – 1) or (i – 1, j). If dp[i – 1][ j] and dp[i][j – 1] are equal, you may
choose either cell.
The resulting string res
will contain the longest common subsequence of x and y.
Example
Let us examine the process
of finding the longest common subsequence (LCS) for two strings provided in the
example.
The search for the LCS starts
at position (i, j) = (6, 7).
y[6] ≠ x[7]: move
to any adjacent cell with the maximum value, for example, (5, 7).
y[5] ≠ x[7]: move to (5, 6).
y[5] = x[6] = ‘b’: make a diagonal move and include the
character ‘b’ in the LCS.
Declare the input strings x and y. To find their LCS, we’ll use the dp array.
#define MAX 1001
int dp[MAX][MAX];
string x, y, res;
Read the input strings. Add a space in front of each of them so that indexing starts from 1.
cin >> x; n =
x.length(); x = " " + x;
cin >> y; m =
y.length(); y = " " + y;
Compute the LCS.
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++)
if (x[i] == y[j])
dp[i][j]
= dp[i - 1][j - 1] + 1;
else
dp[i][j]
= max(dp[i - 1][j], dp[i][j - 1]);
Build the LCS in the string res.
i = n; j = m;
while (i >= 1 && j >= 1)
if (x[i] == y[j])
{
res = res + x[i];
i--;
j--;
}
else
{
if
(dp[i - 1][j] > dp[i][j - 1])
i--;
else
j--;
}
Invert and print the resulting string.
reverse(res.begin(), res.end());
cout << res << endl;