Printing Shortest Common Supersequence

25 Mar, 2022
Given two strings X and Y, print the shortest string that has both X and Y as subsequences. If multiple shortest super-sequence exists, print any one of them.Examples:  
Input: X = "AGGTAB",  Y = "GXTXAYB"
Output: "AGXGTXAYB" OR "AGGXTXAYB" 
OR Any string that represents shortest
supersequence of X and Y

Input: X = "HELLO",  Y = "GEEK"
Output: "GEHEKLLO" OR "GHEEKLLO"
OR Any string that represents shortest 
supersequence of X and Y
 
We have discussed how to print length of shortest possible super-sequence for two given strings here. In this post, we print the shortest super-sequence.We have already discussed below algorithm to find length of shortest super-sequence in previous post- 
Let X[0..m-1] and Y[0..n-1] be two strings and m and be respective 
lengths.

if (m == 0) return n;
if (n == 0) return m;

// If last characters are same, then add 1 to result and
// recur for X[]
if (X[m-1] == Y[n-1]) 
    return 1 + SCS(X, Y, m-1, n-1);

// Else find shortest of following two
//  a) Remove last character from X and recur
//  b) Remove last character from Y and recur
else return 1 + min( SCS(X, Y, m-1, n), SCS(X, Y, m, n-1) );
The following table shows steps followed by the above algorithm if we solve it in bottom-up manner using Dynamic Programming for strings X = “AGGTAB” and Y = “GXTXAYB”,  
Using the DP solution matrix, we can easily print shortest super-sequence of two strings by following below steps – 
We start from the bottom-right most cell of the matrix and 
push characters in output string based on below rules-

 1. If the characters corresponding to current cell (i, j) 
    in X and Y are same, then the character is part of shortest 
    supersequence. We append it in output string and move 
    diagonally to next cell (i.e. (i - 1, j - 1)).

 2. If the characters corresponding to current cell (i, j)
    in X and Y are different, we have two choices -

    If matrix[i - 1][j] > matrix[i][j - 1],
    we add character corresponding to current 
    cell (i, j) in string Y in output string 
    and move to the left cell i.e. (i, j - 1)
    else
    we add character corresponding to current 
    cell (i, j) in string X in output string 
    and move to the top cell i.e. (i - 1, j)

 3. If string Y reaches its end i.e. j = 0, we add remaining
    characters of string X in the output string
    else if string X reaches its end i.e. i = 0, we add 
    remaining characters of string Y in the output string.
Below is the implementation of above idea –  
C++14
Java
Python3
C#
Javascript
/* A dynamic programming based C++ program print   shortest supersequence of two strings */#include <bits/stdc++.h>using namespace std; // returns shortest supersequence of X and Ystring printShortestSuperSeq(string X, string Y){    int m = X.length();    int n = Y.length();     // dp[i][j] contains length of shortest supersequence    // for X[0..i-1] and Y[0..j-1]    int dp[m + 1][n + 1];     // Fill table in bottom up manner    for (int i = 0; i <= m; i++)    {        for (int j = 0; j <= n; j++)        {            // Below steps follow recurrence relation            if(i == 0)                dp[i][j] = j;            else if(j == 0)                dp[i][j] = i;            else if(X[i - 1] == Y[j - 1])                dp[i][j] = 1 + dp[i - 1][j - 1];            else                dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]);        }    }     // Following code is used to print shortest supersequence     // dp[m][n] stores the length of the shortest supersequence    // of X and Y          // string to store the shortest supersequence    string str;     // Start from the bottom right corner and one by one    // push characters in output string    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 shortest supersequence        if (X[i - 1] == Y[j - 1])        {            // Put current character in result            str.push_back(X[i - 1]);             // reduce values of i, j and index            i--, j--;        }         // If current character in X and Y are different        else if (dp[i - 1][j] > dp[i][j - 1])        {            // Put current character of Y in result            str.push_back(Y[j - 1]);             // reduce values of j and index            j--;        }        else        {            // Put current character of X in result            str.push_back(X[i - 1]);             // reduce values of i and index            i--;        }    }     // If Y reaches its end, put remaining characters    // of X in the result string    while (i > 0)    {        str.push_back(X[i - 1]);        i--;    }     // If X reaches its end, put remaining characters    // of Y in the result string    while (j > 0)    {        str.push_back(Y[j - 1]);        j--;    }     // reverse the string and return it    reverse(str.begin(), str.end());    return str;} // Driver program to test above functionint main(){    string X = "AGGTAB";    string Y = "GXTXAYB";     cout << printShortestSuperSeq(X, Y);     return 0;}
/* A dynamic programming based Java program printshortest supersequence of two strings */class GFG {     // returns shortest supersequence of X and Y    static String printShortestSuperSeq(String X, String Y)    {        int m = X.length();        int n = Y.length();         // dp[i][j] contains length of        // shortest supersequence        // for X[0..i-1] and Y[0..j-1]        int dp[][] = new int[m + 1][n + 1];         // Fill table in bottom up manner        for (int i = 0; i <= m; i++)        {            for (int j = 0; j <= n; j++)            {                                 // Below steps follow recurrence relation                if (i == 0)                {                    dp[i][j] = j;                }                else if (j == 0)                {                    dp[i][j] = i;                }                else if (X.charAt(i - 1) == Y.charAt(j - 1))                {                    dp[i][j] = 1 + dp[i - 1][j - 1];                }                else                {                    dp[i][j] = 1 + Math.min(dp[i - 1][j], dp[i][j - 1]);                }            }        }         // Following code is used to print        // shortest supersequence dp[m][n] s        // tores the length of the shortest        // supersequence of X and Y         // string to store the shortest supersequence        String str = "";         // Start from the bottom right corner and one by one        // push characters in output string        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 shortest supersequence            if (X.charAt(i - 1) == Y.charAt(j - 1))                         {                // Put current character in result                str += (X.charAt(i - 1));                 // reduce values of i, j and index                i--;                j--;            }                         // If current character in X and Y are different            else if (dp[i - 1][j] > dp[i][j - 1])            {                                 // Put current character of Y in result                str += (Y.charAt(j - 1));                 // reduce values of j and index                j--;            }            else            {                                 // Put current character of X in result                str += (X.charAt(i - 1));                 // reduce values of i and index                i--;            }        }         // If Y reaches its end, put remaining characters        // of X in the result string        while (i > 0)        {            str += (X.charAt(i - 1));            i--;        }         // If X reaches its end, put remaining characters        // of Y in the result string        while (j > 0)        {            str += (Y.charAt(j - 1));            j--;        }         // reverse the string and return it        str = reverse(str);        return str;    }     static String reverse(String input)    {        char[] temparray = input.toCharArray();        int left, right = 0;        right = temparray.length - 1;         for (left = 0; left < right; left++, right--)        {            // Swap values of left and right            char temp = temparray[left];            temparray[left] = temparray[right];            temparray[right] = temp;        }        return String.valueOf(temparray);    }         // Driver code    public static void main(String[] args)    {        String X = "AGGTAB";        String Y = "GXTXAYB";        System.out.println(printShortestSuperSeq(X, Y));    }} // This code is contributed by 29AjayKumar
# A dynamic programming based Python3 program print# shortest supersequence of two strings # returns shortest supersequence of X and Ydef printShortestSuperSeq(m, n, x, y):     # dp[i][j] contains length of shortest    # supersequence for X[0..i-1] and Y[0..j-1]    dp = [[0 for i in range(n + 1)]             for j in range(m + 1)]     # Fill table in bottom up manner    for i in range(m + 1):        for j in range(n + 1):             # Below steps follow recurrence relation            if i == 0:                dp[i][j] = j            elif j == 0:                dp[i][j] = i            elif x[i - 1] == y[j - 1]:                dp[i][j] = 1 + dp[i - 1][j - 1]            else:                dp[i][j] = 1 + min(dp[i - 1][j],                                   dp[i][j - 1])     # Following code is used to print    # shortest supersequence     # dp[m][n] stores the length of the    # shortest supersequence of X and Y     # string to store the shortest supersequence    string = ""     # Start from the bottom right corner and    # add the characters to the output string    i = m    j = n    while i * j > 0:         # If current character in X and Y are same,        # then current character is part of        # shortest supersequence        if x[i - 1] == y[j - 1]:             # Put current character in result            string = x[i - 1] + string             # reduce values of i, j and index            i -= 1            j -= 1         # If current character in X and Y are different        elif dp[i - 1][j] > dp[i][j - 1]:             # Put current character of Y in result            string = y[j - 1] + string             # reduce values of j and index            j -= 1        else:             # Put current character of X in result            string = x[i - 1] + string             # reduce values of i and index            i -= 1     # If Y reaches its end, put remaining characters    # of X in the result string    while i > 0:        string = x[i - 1] + string        i -= 1     # If X reaches its end, put remaining characters    # of Y in the result string    while j > 0:        string = y[j - 1] + string        j -= 1     return string # Driver Codeif __name__ == "__main__":    x = "GXTXAYB"    y = "AGGTAB"    m = len(x)    n = len(y)         # Take the smaller string as x and larger one as y    if m > n:      x, y = y, x      m, n = n, m         print(*printShortestSuperSeq(m, n, x, y)) # This code is contributed by# sanjeev2552
/* A dynamic programming based C# program printshortest supersequence of two strings */using System; class GFG{     // returns shortest supersequence of X and Y    static String printShortestSuperSeq(String X, String Y)    {        int m = X.Length;        int n = Y.Length;         // dp[i,j] contains length of        // shortest supersequence        // for X[0..i-1] and Y[0..j-1]        int [,]dp = new int[m + 1, n + 1];        int i, j;                 // Fill table in bottom up manner        for (i = 0; i <= m; i++)        {            for (j = 0; j <= n; j++)            {                                 // Below steps follow recurrence relation                if (i == 0)                {                    dp[i, j] = j;                }                else if (j == 0)                {                    dp[i, j] = i;                }                else if (X[i - 1] == Y[j - 1])                {                    dp[i, j] = 1 + dp[i - 1, j - 1];                }                else                {                    dp[i, j] = 1 + Math.Min(dp[i - 1, j], dp[i, j - 1]);                }            }        }         // Following code is used to print        // shortest supersequence dp[m,n] s        // tores the length of the shortest        // supersequence of X and Y         // string to store the shortest supersequence        String str = "";         // Start from the bottom right corner and one by one        // push characters in output string        i = m; j = n;        while (i > 0 && j > 0)                 {            // If current character in X and Y are same, then            // current character is part of shortest supersequence            if (X[i - 1] == Y[j - 1])                         {                // Put current character in result                str += (X[i - 1]);                 // reduce values of i, j and index                i--;                j--;            }                         // If current character in X and Y are different            else if (dp[i - 1, j] > dp[i, j - 1])            {                                 // Put current character of Y in result                str += (Y[j - 1]);                 // reduce values of j and index                j--;            }            else            {                                 // Put current character of X in result                str += (X[i - 1]);                 // reduce values of i and index                i--;            }        }         // If Y reaches its end, put remaining characters        // of X in the result string        while (i > 0)        {            str += (X[i - 1]);            i--;        }         // If X reaches its end, put remaining characters        // of Y in the result string        while (j > 0)        {            str += (Y[j - 1]);            j--;        }         // reverse the string and return it        str = reverse(str);        return str;    }     static String reverse(String input)    {        char[] temparray = input.ToCharArray();        int left, right = 0;        right = temparray.Length - 1;         for (left = 0; left < right; left++, right--)        {            // Swap values of left and right            char temp = temparray[left];            temparray[left] = temparray[right];            temparray[right] = temp;        }        return String.Join("",temparray);    }         // Driver code    public static void Main(String[] args)    {        String X = "AGGTAB";        String Y = "GXTXAYB";        Console.WriteLine(printShortestSuperSeq(X, Y));    }} /* This code has been contributedby PrinciRaj1992*/
<script> /* A dynamic programming based Javascript program printshortest supersequence of two strings */ // returns shortest supersequence of X and Yfunction printShortestSuperSeq(X,Y){         let m = X.length;        let n = Y.length;           // dp[i][j] contains length of        // shortest supersequence        // for X[0..i-1] and Y[0..j-1]        let dp = new Array(m + 1);        for(let i=0;i<(m+1);i++)        {            dp[i]=new Array(n+1);            for(let j=0;j<(n+1);j++)                dp[i][j]=0;        }           // Fill table in bottom up manner        for (let i = 0; i <= m; i++)        {            for (let j = 0; j <= n; j++)            {                                   // Below steps follow recurrence relation                if (i == 0)                {                    dp[i][j] = j;                }                else if (j == 0)                {                    dp[i][j] = i;                }                else if (X[i-1] == Y[j-1])                {                    dp[i][j] = 1 + dp[i - 1][j - 1];                }                else                {                    dp[i][j] =                    1 + Math.min(dp[i - 1][j], dp[i][j - 1]);                }            }        }           // Following code is used to print        // shortest supersequence dp[m][n] s        // tores the length of the shortest        // supersequence of X and Y           // string to store the shortest supersequence        let str = "";           // Start from the bottom right corner and one by one        // push characters in output string        let i = m, j = n;        while (i > 0 && j > 0)                   {            // If current character in X and Y are same, then            // current character is part of shortest supersequence            if (X[i-1] == Y[j-1])                           {                // Put current character in result                str += (X[i-1]);                   // reduce values of i, j and index                i--;                j--;            }                           // If current character in X and Y are different            else if (dp[i - 1][j] > dp[i][j - 1])            {                                   // Put current character of Y in result                str += (Y[j-1]);                   // reduce values of j and index                j--;            }            else            {                                   // Put current character of X in result                str += (X[i-1]);                   // reduce values of i and index                i--;            }        }           // If Y reaches its end, put remaining characters        // of X in the result string        while (i > 0)        {            str += (X[i-1]);            i--;        }           // If X reaches its end, put remaining characters        // of Y in the result string        while (j > 0)        {            str += (Y[j-1]);            j--;        }           // reverse the string and return it        str = reverse(str);        return str;} function reverse(input){    let temparray = input.split("");        let left, right = 0;        right = temparray.length - 1;           for (left = 0; left < right; left++, right--)        {            // Swap values of left and right            let temp = temparray[left];            temparray[left] = temparray[right];            temparray[right] = temp;        }        return (temparray).join("");} // Driver codelet X = "AGGTAB";let Y = "GXTXAYB";document.write(printShortestSuperSeq(X, Y));  // This code is contributed by rag2127 </script>
AGXGTXAYB
Time complexity of above solution is O(n2). Auxiliary space used by the program is O(n2).This article is contributed by Aditya Goel, Krishna Chaitanya Dirisala. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
29AjayKumar
princiraj1992
sanjeev2552
rag2127
abhinabachowdhury
surinderdawra388
krishnadirisala2001
LCS
subsequence
Dynamic Programming
Dynamic Programming
LCS
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.