1+ /*
2+ * Longest Common Subsequence (LCS) Algorithm
3+ *
4+ * Description:
5+ * The Longest Common Subsequence algorithm finds the longest subsequence common to two sequences.
6+ * A subsequence is a sequence that can be derived from another sequence by deleting some or no elements
7+ * without changing the order of the remaining elements.
8+ *
9+ * This implementation uses dynamic programming with a 2D table to solve the problem:
10+ * 1. Create a table to store lengths of LCS for all subproblems
11+ * 2. Fill the table in bottom-up manner
12+ * 3. The value in dp[m][n] contains the length of LCS
13+ * 4. Reconstruct the LCS using the filled table
14+ *
15+ * Time Complexity: O(m*n) where m and n are lengths of the two sequences
16+ * Space Complexity: O(m*n) for the DP table
17+ */
18+
19+ #include < iostream>
20+ #include < vector>
21+ #include < string>
22+ #include < algorithm>
23+
24+ using namespace std ;
25+
26+ // Function to find the length of LCS and the actual LCS
27+ pair<int , string> longestCommonSubsequence (const string& X, const string& Y) {
28+ int m = X.length ();
29+ int n = Y.length ();
30+
31+ // Create a table to store lengths of LCS for all subproblems
32+ vector<vector<int >> dp (m + 1 , vector<int >(n + 1 , 0 ));
33+
34+ // Fill dp[][] in bottom-up manner
35+ for (int i = 1 ; i <= m; i++) {
36+ for (int j = 1 ; j <= n; j++) {
37+ if (X[i - 1 ] == Y[j - 1 ]) {
38+ dp[i][j] = dp[i - 1 ][j - 1 ] + 1 ;
39+ } else {
40+ dp[i][j] = max (dp[i - 1 ][j], dp[i][j - 1 ]);
41+ }
42+ }
43+ }
44+
45+ // Length of LCS is dp[m][n]
46+ int lcsLength = dp[m][n];
47+
48+ // Reconstruct the LCS
49+ string lcs = " " ;
50+ int i = m, j = n;
51+
52+ while (i > 0 && j > 0 ) {
53+ // If current characters match, include in LCS
54+ if (X[i - 1 ] == Y[j - 1 ]) {
55+ lcs = X[i - 1 ] + lcs;
56+ i--;
57+ j--;
58+ }
59+ // Move in the direction of larger value
60+ else if (dp[i - 1 ][j] > dp[i][j - 1 ]) {
61+ i--;
62+ } else {
63+ j--;
64+ }
65+ }
66+
67+ return {lcsLength, lcs};
68+ }
69+
70+ // Function to print the DP table (for educational purposes)
71+ void printDPTable (const string& X, const string& Y, const vector<vector<int >>& dp) {
72+ int m = X.length ();
73+ int n = Y.length ();
74+
75+ cout << " DP Table:" << endl;
76+ cout << " " ;
77+ for (int j = 0 ; j < n; j++) {
78+ cout << Y[j] << " " ;
79+ }
80+ cout << endl;
81+
82+ for (int i = 0 ; i <= m; i++) {
83+ if (i == 0 ) {
84+ cout << " " ;
85+ } else {
86+ cout << X[i - 1 ] << " " ;
87+ }
88+
89+ for (int j = 0 ; j <= n; j++) {
90+ cout << dp[i][j] << " " ;
91+ }
92+ cout << endl;
93+ }
94+ }
95+
96+ // Main function with test cases
97+ int main () {
98+ // Test Case 1: Basic example
99+ cout << " Test Case 1:" << endl;
100+ string X1 = " ABCDGH" ;
101+ string Y1 = " AEDFHR" ;
102+ cout << " String 1: " << X1 << endl;
103+ cout << " String 2: " << Y1 << endl;
104+
105+ auto result1 = longestCommonSubsequence (X1, Y1);
106+ cout << " Length of LCS: " << result1.first << endl;
107+ cout << " LCS: " << result1.second << endl << endl;
108+
109+ // Test Case 2: No common characters
110+ cout << " Test Case 2:" << endl;
111+ string X2 = " ABC" ;
112+ string Y2 = " DEF" ;
113+ cout << " String 1: " << X2 << endl;
114+ cout << " String 2: " << Y2 << endl;
115+
116+ auto result2 = longestCommonSubsequence (X2, Y2);
117+ cout << " Length of LCS: " << result2.first << endl;
118+ cout << " LCS: " << result2.second << endl << endl;
119+
120+ // Test Case 3: One string is a subsequence of the other
121+ cout << " Test Case 3:" << endl;
122+ string X3 = " ABCDEFG" ;
123+ string Y3 = " ACG" ;
124+ cout << " String 1: " << X3 << endl;
125+ cout << " String 2: " << Y3 << endl;
126+
127+ auto result3 = longestCommonSubsequence (X3, Y3);
128+ cout << " Length of LCS: " << result3.first << endl;
129+ cout << " LCS: " << result3.second << endl << endl;
130+
131+ // Test Case 4: Both strings are identical
132+ cout << " Test Case 4:" << endl;
133+ string X4 = " PROGRAMMING" ;
134+ string Y4 = " PROGRAMMING" ;
135+ cout << " String 1: " << X4 << endl;
136+ cout << " String 2: " << Y4 << endl;
137+
138+ auto result4 = longestCommonSubsequence (X4, Y4);
139+ cout << " Length of LCS: " << result4.first << endl;
140+ cout << " LCS: " << result4.second << endl;
141+
142+ return 0 ;
143+ }
0 commit comments