Printing Longest Common Subsequence - GeeksforGeeks

12 Apr, 2022
Given two sequences, print the longest subsequence present in both of them. Examples: LCS for input Sequences “ABCDGH” and “AEDFHR” is “ADH” of length 3. LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.We have discussed Longest Common Subsequence (LCS) problem in a previous post. The function discussed there was mainly to find the length of LCS. To find length of LCS, a 2D table L[][] was constructed. In this post, the function to construct and print LCS is discussed.Following is detailed algorithm to print the LCS. It uses the same 2D table L[][].1) Construct L[m+1][n+1] using the steps discussed in previous post.2) The value L[m][n] contains length of LCS. Create a character array lcs[] of length equal to the length of lcs plus 1 (one extra to store \0).3) Traverse the 2D array starting from L[m][n]. Do following for every cell L[i][j] .....a) If characters (in X and Y) corresponding to L[i][j] are same (Or X[i-1] == Y[j-1]), then include this character as part of LCS. .....b) Else compare values of L[i-1][j] and L[i][j-1] and go in direction of greater value.The following table (taken from Wiki) shows steps (highlighted) followed by the above algorithm. 
 
Following is the implementation of above approach.  
C++14
Java
Python3
C#
PHP
Javascript
/* Dynamic Programming implementation of LCS problem */#include <cstdlib>#include <cstring>#include <iostream>using namespace std; /* Returns length of LCS for X[0..m-1], Y[0..n-1] */void lcs(char* X, char* Y, int m, int n){    int L[m + 1][n + 1];     /* Following steps build L[m+1][n+1] in bottom up      fashion. Note that L[i][j] contains length of LCS of      X[0..i-1] and Y[0..j-1] */    for (int i = 0; i <= m; i++) {        for (int j = 0; j <= n; j++) {            if (i == 0 || j == 0)                L[i][j] = 0;            else if (X[i - 1] == Y[j - 1])                L[i][j] = L[i - 1][j - 1] + 1;            else                L[i][j] = max(L[i - 1][j], L[i][j - 1]);        }    }     // Following code is used to print LCS    int index = L[m][n];     // Create a character array to store the lcs string    char lcs[index + 1];    lcs[index] = '\0'; // Set the terminating character     // Start from the right-most-bottom-most corner and    // one by one store characters in lcs[]    int i = m, j = n;    while (i > 0 && j > 0) {        // If current character in X[] and Y are same, then        // current character is part of LCS        if (X[i - 1] == Y[j - 1]) {            lcs[index - 1]                = X[i - 1]; // Put current character in result            i--;            j--;            index--; // reduce values of i, j and index        }         // If not same, then find the larger of two and        // go in the direction of larger value        else if (L[i - 1][j] > L[i][j - 1])            i--;        else            j--;    }     // Print the lcs    cout << "LCS of " << X << " and " << Y << " is " << lcs;} /* Driver program to test above function */int main(){    char X[] = "AGGTAB";    char Y[] = "GXTXAYB";    int m = strlen(X);    int n = strlen(Y);    lcs(X, Y, m, n);    return 0;}
// Dynamic Programming implementation of LCS problem in Javaimport java.io.*; class LongestCommonSubsequence {    // Returns length of LCS for X[0..m-1], Y[0..n-1]    static void lcs(String X, String Y, int m, int n)    {        int[][] L = new int[m + 1][n + 1];         // Following steps build L[m+1][n+1] in bottom up        // fashion. Note that L[i][j] contains length of LCS        // of X[0..i-1] and Y[0..j-1]        for (int i = 0; i <= m; i++) {            for (int j = 0; j <= n; j++) {                if (i == 0 || j == 0)                    L[i][j] = 0;                else if (X.charAt(i - 1) == Y.charAt(j - 1))                    L[i][j] = L[i - 1][j - 1] + 1;                else                    L[i][j] = Math.max(L[i - 1][j],                                       L[i][j - 1]);            }        }         // Following code is used to print LCS        int index = L[m][n];        int temp = index;         // Create a character array to store the lcs string        char[] lcs = new char[index + 1];        lcs[index]            = '\u0000'; // Set the terminating character         // Start from the right-most-bottom-most corner and        // one by one store characters in lcs[]        int i = m;        int j = n;        while (i > 0 && j > 0) {            // If current character in X[] and Y are same,            // then current character is part of LCS            if (X.charAt(i - 1) == Y.charAt(j - 1)) {                // Put current character in result                lcs[index - 1] = X.charAt(i - 1);                 // reduce values of i, j and index                i--;                j--;                index--;            }             // If not same, then find the larger of two and            // go in the direction of larger value            else if (L[i - 1][j] > L[i][j - 1])                i--;            else                j--;        }         // Print the lcs        System.out.print("LCS of " + X + " and " + Y                         + " is ");        for (int k = 0; k <= temp; k++)            System.out.print(lcs[k]);    }     // driver program    public static void main(String[] args)    {        String X = "AGGTAB";        String Y = "GXTXAYB";        int m = X.length();        int n = Y.length();        lcs(X, Y, m, n);    }} // Contributed by Pramod Kumar
# Dynamic programming implementation of LCS problem # Returns length of LCS for X[0..m-1], Y[0..n-1]  def lcs(X, Y, m, n):    L = [[0 for i in range(n+1)] for j in range(m+1)]     # Following steps build L[m+1][n+1] in bottom up fashion. Note    # that 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:                L[i][j] = 0            elif X[i-1] == Y[j-1]:                L[i][j] = L[i-1][j-1] + 1            else:                L[i][j] = max(L[i-1][j], L[i][j-1])         # Create a string variable to store the lcs string    lcs = ""     # Start from the right-most-bottom-most corner and    # one by one store characters in lcs[]    i = m    j = n    while i > 0 and j > 0:         # If current character in X[] and Y are same, then        # current character is part of LCS        if X[i-1] == Y[j-1]:            lcs += X[i-1]            i -= 1            j -= 1         # If not same, then find the larger of two and        # go in the direction of larger value        elif L[i-1][j] > L[i][j-1]:            i -= 1                     else:            j -= 1     # We traversed the table in reverse order    # LCS is the reverse of what we got    lcs = lcs[::-1]    print("LCS of " + X + " and " + Y + " is " + lcs)  # Driver programX = "AGGTAB"Y = "GXTXAYB"m = len(X)n = len(Y)lcs(X, Y, m, n) # This code is contributed by AMAN ASATI
// Dynamic Programming implementation// of LCS problem in C#using System; class GFG {    // Returns length of LCS for X[0..m-1], Y[0..n-1]    static void lcs(String X, String Y, int m, int n)    {        int[, ] L = new int[m + 1, n + 1];         // Following steps build L[m+1][n+1] in        // bottom up fashion. Note that L[i][j]        // contains length of LCS of X[0..i-1]        // and Y[0..j-1]        for (int i = 0; i <= m; i++) {            for (int j = 0; j <= n; j++) {                if (i == 0 || j == 0)                    L[i, j] = 0;                else if (X[i - 1] == Y[j - 1])                    L[i, j] = L[i - 1, j - 1] + 1;                else                    L[i, j] = Math.Max(L[i - 1, j],                                       L[i, j - 1]);            }        }         // Following code is used to print LCS        int index = L[m, n];        int temp = index;         // Create a character array        // to store the lcs string        char[] lcs = new char[index + 1];         // Set the terminating character        lcs[index] = '\0';         // Start from the right-most-bottom-most corner        // and one by one store characters in lcs[]        int k = m, l = n;        while (k > 0 && l > 0) {            // If current character in X[] and Y            // are same, then current character            // is part of LCS            if (X[k - 1] == Y[l - 1]) {                // Put current character in result                lcs[index - 1] = X[k - 1];                 // reduce values of i, j and index                k--;                l--;                index--;            }             // If not same, then find the larger of two and            // go in the direction of larger value            else if (L[k - 1, l] > L[k, l - 1])                k--;            else                l--;        }         // Print the lcs        Console.Write("LCS of " + X + " and " + Y + " is ");        for (int q = 0; q <= temp; q++)            Console.Write(lcs[q]);    }     // Driver program    public static void Main()    {        String X = "AGGTAB";        String Y = "GXTXAYB";        int m = X.Length;        int n = Y.Length;        lcs(X, Y, m, n);    }} // This code is contributed by Sam007
<?php// Dynamic Programming implementation of LCS problem // Returns length of LCS for X[0..m-1], Y[0..n-1]function lcs( $X, $Y, $m, $n ){    $L = array_fill(0, $m + 1,         array_fill(0, $n + 1, NULL));         /* Following steps build L[m+1][n+1] in bottom       up fashion. Note that L[i][j] contains length       of LCS of X[0..i-1] and Y[0..j-1] */    for ($i = 0; $i <= $m; $i++)    {        for ($j = 0; $j <= $n; $j++)        {            if ($i == 0 || $j == 0)                $L[$i][$j] = 0;            else if ($X[$i - 1] == $Y[$j - 1])                $L[$i][$j] = $L[$i - 1][$j - 1] + 1;            else                $L[$i][$j] = max($L[$i - 1][$j],                                 $L[$i][$j - 1]);        }    }         // Following code is used to print LCS    $index = $L[$m][$n];    $temp = $index;         // Create a character array to store the lcs string    $lcs = array_fill(0, $index + 1, NULL);    $lcs[$index] = ''; // Set the terminating character         // Start from the right-most-bottom-most corner    // and one by one store characters in lcs[]    $i = $m;    $j = $n;    while ($i > 0 && $j > 0)    {        // If current character in X[] and Y are same,        // then current character is part of LCS        if ($X[$i - 1] == $Y[$j - 1])        {            // Put current character in result            $lcs[$index - 1] = $X[$i - 1];            $i--;            $j--;            $index--;    // reduce values of i, j and index        }             // If not same, then find the larger of two        // and go in the direction of larger value        else if ($L[$i - 1][$j] > $L[$i][$j - 1])            $i--;        else            $j--;    }         // Print the lcs    echo "LCS of " . $X . " and " . $Y . " is ";    for($k = 0; $k < $temp; $k++)        echo $lcs[$k];} // Driver Code$X = "AGGTAB";$Y = "GXTXAYB";$m = strlen($X);$n = strlen($Y);lcs($X, $Y, $m, $n); // This code is contributed by ita_c?>
<script>function ReverseString(str) {   return str.split('').reverse().join('')}   function max(a, b){    if (a > b)        return a;    else        return b;}function printLCS(str1, str2) {    var len1 = str1.length;    var len2 = str2.length;    var lcs = new Array(len1 + 1);    for (var i = 0; i <= len1; i++) {        lcs[i] = new Array(len2 + 1)    }    for (var i = 0; i <= len1; i++) {        for (var j = 0; j <= len2; j++) {            if (i == 0 || j == 0) {                lcs[i][j] = 0;            }            else {                if (str1[i - 1] == str2[j - 1]) {                    lcs[i][j] = 1 + lcs[i - 1][j - 1];                }                else {                    lcs[i][j] = max(lcs[i][j - 1], lcs[i - 1][j]);                }            }        }}                var n = lcs[len1][len2];         document.write("Length of common subsequence is: " +         n + "<br>" + "The subsequence is : ");        var str="";       var i = len1;       var j = len2;       while(i>0&&j>0)       {            if(str1[i - 1] == str2[j - 1])            {                str += str1[i - 1];                i--;                j--;            }            else{            if(lcs[i][j-1]>lcs[i-1][j])            {                j--;            }            else            {                i--;            }            }        }       return ReverseString(str);    }    var str1 = "AGGTAB";    var str2 = "GXTXAYB";    document.write(printLCS(str1, str2));         // This code is contributed by akshitsaxenaa09</script>
LCS of AGGTAB and GXTXAYB is GTAB
Output: 
LCS of AGGTAB and GXTXAYB is GTAB
 
YouTubeGeeksforGeeks507K subscribersDynamic Programming | Set 4 (Longest Common Subsequence) | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 8:14•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=HgUOWB0StNE" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
References: http://en.wikipedia.org/wiki/Longest_common_subsequence_problemPlease write comments if you find anything incorrect, or you want to share more information about the topic discussed above 
Sam007
ukasp
abhishek_987
divamkachoria
surinderdawra388
akshitsaxenaa09
amartyaghoshgfg
amanasati1
LCS
subsequence
Strings
Strings
LCS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Check for Balanced Brackets in an expression (well-formedness) using Stack
Python program to check if a string is palindrome or not
KMP Algorithm for Pattern Searching
Array of Strings in C++ (5 Different Ways to Create)
Different methods to reverse a string in C/C++
Convert string to char array in C++
Longest Palindromic Substring | Set 1
Caesar Cipher in Cryptography
Check whether two strings are anagram of each other
Length of the longest substring without repeating characters