Shortest Common Supersequence in C++


Suppose we have two strings str1 and str2, we have to find the shortest string that has both str1 and str2 as subsequences. There may be more than one results, so we will return only one of them.

As you know a string S is called a subsequence of string T if deleting some number of characters from T (possibly 0, and the characters are chosen anywhere from T) results in the string S.

So, if the input is like "acab", "bac", then the output will be "bacab", this is because two given strings are subsequence of this.

To solve this, we will follow these steps −

  • Define a function getLCS(), this will take s1, s2,

  • ret := empty string

  • n := size of s1, m := size of s2

  • Define one 2D array dp of size (n + 1) x (m + 1)

  • i := n, j := m

  • s1 := concatenate blank string before s1

  • s2 := concatenate blank string before s2

  • for initialize i := 1, when i <= n, update (increase i by 1), do −

    • for initialize j := 1, when j <= m, update (increase j by 1), do −

      • if s1[i] is same as s2[j], then −

        • dp[i, j] := 1 + dp[i - 1, j - 1]

      • Otherwise

        • dp[i, j] := maximum of dp[i - 1, j] and dp[i, j - 1]

  • while (i is non-zero and j is non-zero), do −

    • if dp[i, j] is same as dp[i - 1, j], then −

      • (decrease i by 1)

      • Ignore following part, skip to the next iteration

    • if dp[i, j] is same as dp[i, j - 1], then −

      • (decrease j by 1)

      • Ignore following part, skip to the next iteration

    • ret := ret + s1[i]

    • (decrease i by 1)

    • (decrease j by 1)

  • reverse the array ret

  • return ret

  • From the main method do the following −

  • s3 := getLCS(str1, str2)

  • ret := empty string, i := 0, j := 0, k := 0

  • while k < size of s3, do −

    • if i < size of str1 and str1[i] is not equal to s3[k], then −

      • ret := ret + str1[i]

      • (increase i by 1)

      • Ignore following part, skip to the next iteration

    • if j < size of str2 and str2[j] is not equal to s3[k], then −

      • ret := ret + str2[j]

      • (increase j by 1)

      • Ignore following part, skip to the next iteration

    • ret := ret + s3[k]

    • (increase i, j, k by 1)

  • while i < size of str1, do −

    • ret := ret + str1[i]

    • (increase i by 1)

  • while j < size of str2, do −

    • ret := ret + str2[j]

    • (increase j by 1)

  • return ret

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class Solution {
   public:
   string shortestCommonSupersequence(string str1, string str2){
      string s3 = getLCS(str1, str2);
      string ret = "";
      int i = 0;
      int j = 0;
      int k = 0;
      while (k < s3.size()) {
         if (i < str1.size() && str1[i] != s3[k]) {
            ret += str1[i];
            i++;
            continue;
         }
         if (j < str2.size() && str2[j] != s3[k]) {
            ret += str2[j];
            j++;
            continue;
         }
         ret += s3[k];
         k++;
         i++;
         j++;
      }
      while (i < str1.size()) {
         ret += str1[i];
         i++;
      }
      while (j < str2.size()) {
         ret += str2[j];
         j++;
      }
      return ret;
   }
   string getLCS(string s1, string s2){
      string ret = "";
      int n = s1.size();
      int m = s2.size();
      vector<vector<int> > dp(n + 1, vector<int>(m + 1));
      int i = n;
      int j = m;
      s1 = " " + s1;
      s2 = " " + s2;
      for (int i = 1; i <= n; i++) {
         for (int j = 1; j <= m; j++) {
            if (s1[i] == s2[j]) {
               dp[i][j] = 1 + dp[i - 1][j - 1];
            } else {
               dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
         }
      }
      while (i && j) {
         if (dp[i][j] == dp[i - 1][j]) {
            i--;
            continue;
         }
         if (dp[i][j] == dp[i][j - 1]) {
            j--;
            continue;
         }
         ret += s1[i];
         i--;
         j--;
      }
      reverse(ret.begin(), ret.end());
      return ret;
   }
};
main(){
   Solution ob;
   cout << (ob.shortestCommonSupersequence("acab", "bac"));
}

Input

"acab", "bac"

Output

bacab

Updated on: 04-Jun-2020

113 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements