Shortest possible combination of two strings

Compute the shortest string for a combination of two given strings such that the new string consist of both the strings as its subsequences.

Examples:

Input : a = "pear"
        b = "peach"
Output : pearch
pearch is the shorted string such that both
pear and peach are its subsequences.

Input  : a = "geek"
         b = "code"
Output : gecodek

We have discussed a solution to find length of the shortest supersequence in below post.
Shortest Common Supersequence

In this post, printing of supersequence is discussed. The solution is based on below recursive approach discussed in above post as an alternate method.

Let a[0..m-1] and b[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 a[]
  if (a[m-1] == b[n-1]) 
     return 1 + SCS(a, b, 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(a, b, m-1, n), 
                       SCS(a, b, m, n-1) );

We build a DP array to store lengths. After building the DP array, we traverse from bottom right most position. The approach of printing is similar to printing LCS.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

/* C++ program to print supersequence of two
   strings */
#include<bits/stdc++.h>
using namespace std;
  
/* Prints super sequence of a[0..m-1] and b[0..n-1] */
void printSuperSeq(string &a, string &b)
{
    int m = a.length(), n = b.length();
    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 above recurrence
           if (!i)
               dp[i][j] = j;
           else if (!j)
               dp[i][j] = i;
           else if (a[i-1] == b[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 supersequence
   int index = dp[m][n];
  
   // Create a string of size index+1 to store the result
   string res(index+1, '\0');
  
   // Start from the right-most-bottom-most corner and
   // one by one store characters in res[]
   int i = m, j = n;
   while (i > 0 && j > 0)
   {
      // If current character in a[] and b are same,
      // then current character is part of LCS
      if (a[i-1] == b[j-1])
      {
          // Put current character in result
          res[index-1] = a[i-1];
  
          // reduce values of i, j and indexs
          i--; j--; index--;
      }
  
      // If not same, then find the larger of two and
      // go in the direction of larger value
      else if (dp[i-1][j] < dp[i][j-1])
      { res[index-1] = a[i-1];   i--;  index--; }
      else
      { res[index-1] = b[j-1];  j--; index--; }
   }
  
   // Copy remaining characters of string 'a'
   while (i > 0)
   {
       res[index-1] = a[i-1];   i--;  index--;
   }
  
   // Copy remaining characters of string 'b'
   while (j > 0)
   {
       res[index-1] = b[j-1];  j--; index--;
   }
  
   // Print the result
   cout << res;
}
  
/* Driver program to test above function */
int main()
{
  string a = "algorithm", b = "rhythm";
  printSuperSeq(a, b);
  return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to print supersequence of two
// strings 
public class GFG_1 {
      
    String a , b;
      
    // Prints super sequence of a[0..m-1] and b[0..n-1] 
    static void printSuperSeq(String a, String b)
    {
        int m = a.length(), n = b.length();
        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 above recurrence
               if (i == 0)
                   dp[i][j] = j;
               else if (j == 0 )
                   dp[i][j] = i;
               else if (a.charAt(i-1) == b.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]);
            }
        }
       
       // Create a string of size index+1 to store the result
       String res = "";
       
       // Start from the right-most-bottom-most corner and
       // one by one store characters in res[]
       int i = m, j = n;
       while (i > 0 && j > 0)
       {
          // If current character in a[] and b are same,
          // then current character is part of LCS
          if (a.charAt(i-1) == b.charAt(j-1))
          {
              // Put current character in result
              res = a.charAt(i-1) + res;
       
              // reduce values of i, j and indexs
              i--;
              j--;
          }
       
          // If not same, then find the larger of two and
          // go in the direction of larger value
          else if (dp[i-1][j] < dp[i][j-1])
          
              res = a.charAt(i-1) + res;
              i--;  
          }
          else
          {
              res = b.charAt(j-1) + res; 
              j--; 
          }
       }
       
       // Copy remaining characters of string 'a'
       while (i > 0)
       {
           res = a.charAt(i-1) + res;
           i--;
       }
       
       // Copy remaining characters of string 'b'
       while (j > 0)
       {
           res = b.charAt(j-1) + res;   
           j--; 
       }
       
       // Print the result
       System.out.println(res);
    }
       
    /* Driver program to test above function */
    public static void main(String args[])
    {
      String a = "algorithm";
      String b = "rhythm";
      printSuperSeq(a, b);
        
    }
}
// This article is contributed by Sumit Ghosh

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to print supersequence of two
// strings
using System; 
public class GFG_1 {
       
    
    // Prints super sequence of a[0..m-1] and b[0..n-1] 
    static void printSuperSeq(string a, string b)
    {
        int m = a.Length, n = b.Length;
        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 above recurrence
               if (i == 0)
                   dp[i,j] = j;
               else if (j == 0 )
                   dp[i,j] = i;
               else if (a[i-1] == b[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]);
            }
        }
        
       // Create a string of size index+1 to store the result
       string res = "";
        
       // Start from the right-most-bottom-most corner and
       // one by one store characters in res[]
       int k = m, l = n;
       while (k > 0 && l > 0)
       {
          // If current character in a[] and b are same,
          // then current character is part of LCS
          if (a[k-1] == b[l-1])
          {
              // Put current character in result
              res = a[k-1] + res;
        
              // reduce values of i, j and indexs
              k--;
              l--;
          }
        
          // If not same, then find the larger of two and
          // go in the direction of larger value
          else if (dp[k-1,l] < dp[k,l-1])
          
              res = a[k-1] + res;
              k--;  
          }
          else
          {
              res = b[l-1] + res; 
              l--; 
          }
       }
        
       // Copy remaining characters of string 'a'
       while (k > 0)
       {
           res = a[k-1] + res;
           k--;
       }
        
       // Copy remaining characters of string 'b'
       while (l > 0)
       {
           res = b[l-1] + res;   
           l--; 
       }
        
       // Print the result
       Console.WriteLine(res);
    }
        
    /* Driver program to test above function */
    public static void Main()
    {
      string a = "algorithm";
      string b = "rhythm";
      printSuperSeq(a, b);
         
    }
}
// This article is contributed by Ita_c.

chevron_right