📜  两根字符串的最短组合

📅  最后修改于: 2021-04-29 15:40:13             🧑  作者: Mango

计算两个给定字符串组合的最短字符串,以使新字符串包含两个字符串作为其子序列。
例子:

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

我们在下面的文章中讨论了找到最短超序列长度的解决方案。
最短的通用超序列
在这篇文章中,讨论了超序列的打印。该解决方案基于上文中讨论的以下递归方法作为替代方法。

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) );

我们构建一个DP数组来存储长度。构建完DP数组后,我们从最右下角开始遍历。打印方法类似于打印LCS。

C++
/* C++ program to print supersequence of two
   strings */
#include
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 smaller of two and
      // go in the direction of smaller 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;
}


Java
// 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


Python3
# Python3 program to print supersequence of two strings
 
# Prints super sequence of a[0..m-1] and b[0..n-1]
def printSuperSeq(a, b):
    m = len(a)
    n = len(b)
    dp = [[0] * (n + 1) for i in range(m + 1)]
 
    # Fill table in bottom up manner
    for i in range(0, m + 1):
        for j in range(0, n + 1):
             
            # Below steps follow above recurrence
            if not i:
                dp[i][j] = j;
            elif not j:
                dp[i][j] = i;
            elif (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
    index = dp[m][n];
 
    # Create a string of size index+1
    # to store the result
    res = [""] * (index)
 
    # Start from the right-most-bottom-most corner
    # and one by one store characters in res[]
    i = m
    j = n;
    while (i > 0 and 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 -= 1
            j -= 1
            index -= 1
         
        # If not same, then find the larger of two and
        # go in the direction of larger value
        elif (dp[i - 1][j] < dp[i][j - 1]):
            res[index - 1] = a[i - 1]
            i -= 1
            index -= 1
 
        else:
            res[index - 1] = b[j - 1]
            j -= 1
            index -= 1
 
    # Copy remaining characters of string 'a'
    while (i > 0):
        res[index - 1] = a[i - 1]
        i -= 1
        index -= 1
 
    # Copy remaining characters of string 'b'
    while (j > 0):
        res[index - 1] = b[j - 1]
        j -= 1
        index -= 1
 
    # Print the result
    print("".join(res))
 
# Driver Code
if __name__ == '__main__':
    a = "algorithm"
    b = "rhythm"
    printSuperSeq(a, b)
     
# This code is contributed by ashutosh450


C#
// 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.


C++
// C++ implementation to find shortest string for
// a combination of two strings
#include 
using namespace std;
 
// Vector that store the index of string a and b
vector index_a;
vector index_b;
 
// Subroutine to Backtrack the dp matrix to
// find the index vector traversing which would
// yield the shortest possible combination
void index(int dp[][100], string a, string b,
           int size_a, int size_b)
{
    // Clear the index vectors
    index_a.clear();
    index_b.clear();
 
    // Return if either of a or b is reduced
    // to 0
    if (size_a == 0 || size_b == 0)
        return;
 
    // Push both to index_a and index_b with
    // the respective a and b index
    if (a[size_a - 1] == b[size_b - 1]) {
        index(dp, a, b, size_a - 1, size_b - 1);
        index_a.push_back(size_a - 1);
        index_b.push_back(size_b - 1);
    } else {
        if (dp[size_a - 1][size_b] > dp[size_a]
                                    [size_b - 1]) {
            index(dp, a, b, size_a - 1, size_b);
        } else {
            index(dp, a, b, size_a, size_b - 1);
        }
    }
}
 
// function to combine the strings to form
// the shortest string
void combine(string a, string b, int size_a,
             int size_b)
{
 
    int dp[100][100];
    string ans = "";
    int k = 0;
 
    // Initialize the matrix to 0
    memset(dp, 0, sizeof(dp));
 
    // Store the increment of diagonally
    // previous value if a[i-1] and b[j-1] are
    // equal, else store the max of dp[i][j-1]
    // and dp[i-1][j]
    for (int i = 1; i <= size_a; i++) {
        for (int j = 1; j <= size_b; j++) {
            if (a[i - 1] == b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = max(dp[i][j - 1],
                               dp[i - 1][j]);
            }
        }
    }
 
    // Get the Lowest Common Subsequence
    int lcs = dp[size_a][size_b];
 
    // Backtrack the dp array to get the index
    // vectors of two strings, used to find
    // the shortest possible combination.
    index(dp, a, b, size_a, size_b);
 
    int i, j = i = k;
 
    // Build the string combination using the
    // index found by backtracking
    while (k < lcs) {
        while (i < size_a && i < index_a[k]) {
            ans += a[i++];
        }
 
        while (j < size_b && j < index_b[k]) {
            ans += b[j++];
        }
 
        ans = ans + a[index_a[k]];
        k++;
        i++;
        j++;
    }
 
    // Append the remaining characters in a
    // to answer
    while (i < size_a) {
        ans += a[i++];
    }
 
    // Append the remaining characters in b
    // to answer
    while (j < size_b) {
        ans += b[j++];
    }
 
    cout << ans;
}
 
// Driver code
int main()
{
    string a = "algorithm";
    string b = "rhythm";
 
    // Store the length of string
    int size_a = a.size();
    int size_b = b.size();
 
    combine(a, b, size_a, size_b);
    return 0;
}


Java
// Java implementation to find shortest string for
// a combination of two strings
import java.util.ArrayList;
public class GFG_2 {
          
    // Vector that store the index of string a and b
    static ArrayList index_a = new ArrayList<>();
    static ArrayList index_b = new ArrayList<>();
      
    // Subroutine to Backtrack the dp matrix to
    // find the index vector traversing which would
    // yield the shortest possible combination
    static void index(int dp[][], String a, String b,
               int size_a, int size_b)
    {
        // Clear the index vectors
        index_a.clear();
        index_b.clear();
      
        // Return if either of a or b is reduced
        // to 0
        if (size_a == 0 || size_b == 0)
            return;
      
        // Push both to index_a and index_b with
        // the respective a and b index
        if (a.charAt(size_a - 1) == b.charAt(size_b - 1)) {
            index(dp, a, b, size_a - 1, size_b - 1);
            index_a.add(size_a - 1);
            index_b.add(size_b - 1);
        } else {
            if (dp[size_a - 1][size_b] > dp[size_a]
                                        [size_b - 1]) {
                index(dp, a, b, size_a - 1, size_b);
            } else {
                index(dp, a, b, size_a, size_b - 1);
            }
        }
    }
      
    // function to combine the strings to form
    // the shortest string
    static void combine(String a, String b, int size_a,
                 int size_b)
    {
      
        int[][] dp = new int[100][100];
        String ans = "";
        int k = 0;
      
        // Store the increment of diagonally
        // previous value if a[i-1] and b[j-1] are
        // equal, else store the max of dp[i][j-1]
        // and dp[i-1][j]
        for (int i = 1; i <= size_a; i++) {
            for (int j = 1; j <= size_b; j++) {
                if (a.charAt(i - 1) == b.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j - 1],
                                   dp[i - 1][j]);
                }
            }
        }
      
        // Get the Lowest Common Subsequence
        int lcs = dp[size_a][size_b];
      
        // Backtrack the dp array to get the index
        // vectors of two strings, used to find
        // the shortest possible combination.
        index(dp, a, b, size_a, size_b);
      
        int i, j = i = k;
      
        // Build the string combination using the
        // index found by backtracking
        while (k < lcs) {
            while (i < size_a && i < index_a.get(k)) {
                ans += a.charAt(i++);
            }
      
            while (j < size_b && j < index_b.get(k)) {
                ans += b.charAt(j++);
            }
      
            ans = ans + a.charAt(index_a.get(k));
            k++;
            i++;
            j++;
        }
      
        // Append the remaining characters in a
        // to answer
        while (i < size_a) {
            ans += a.charAt(i++);
        }
      
        // Append the remaining characters in b
        // to answer
        while (j < size_b) {
            ans +=  b.charAt(j++);
        }
      
        System.out.println(ans);
    }
      
      
    /* Driver program to test above function */
    public static void main(String args[])
    {
      String a = "algorithm";
      String b = "rhythm";
      combine(a, b, a.length(),b.length());
       
    }
}
// This article is contributed by Sumit Ghosh


Python3
# Python implementation to find shortest string for
# a combination of two strings
index_a = []
index_b = []
 
def index(dp, a, b, size_a, size_b):
    if (size_a == 0 or size_b == 0):
        return
    if (a[size_a - 1] == b[size_b - 1]):
        index(dp, a, b, size_a - 1, size_b - 1)
        index_a.append(size_a - 1)
        index_b.append(size_b - 1)
    else:
        if(dp[size_a - 1][size_b] > dp[size_a][size_b - 1]):
            index(dp, a, b, size_a - 1, size_b)
        else:
            index(dp, a, b, size_a, size_b - 1)
     
def combine(a, b, size_a, size_b):
    dp = [[0 for i in range(100)] for j in range(100)]
    ans = ""
    k = 0
     
    for i in range(1, size_a + 1):
        for j in range(1, size_b + 1):
            if(a[i - 1] == b[j - 1]):
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
     
    lcs = dp[size_a][size_b]
    index(dp, a, b, size_a, size_b)
    j = i = k
    while (k < lcs):
        while (i < size_a and i < index_a[k]):
            ans += a[i];
            i += 1
        while (j < size_b and j < index_b[k]):
            ans += b[j]
            j += 1
        ans = ans + a[index_a[k]]
        k += 1
        i += 1
        j += 1
     
    while (i < size_a):
        ans += a[i]
        i += 1
    while (j < size_b):
        ans += b[j]
        j += 1
    print(ans)
 
# Driver code
a = "algorithm"
b = "rhythm"
size_a = len(a)
size_b = len(b)
combine(a, b, size_a, size_b)
 
# This code is contributed by avanitrachhadiya2155


C#
// C# implementation to find shortest string for
// a combination of two strings
using System;
using System.Collections.Generic;
 
class GFG
{
         
    // Vector that store the index of string a and b
    static List index_a = new List();
    static List index_b = new List();
     
    // Subroutine to Backtrack the dp matrix to
    // find the index vector traversing which would
    // yield the shortest possible combination
    static void index(int [,]dp, String a, String b,
                      int size_a, int size_b)
    {
        // Clear the index vectors
        index_a.Clear();
        index_b.Clear();
     
        // Return if either of a or b is reduced
        // to 0
        if (size_a == 0 || size_b == 0)
            return;
     
        // Push both to index_a and index_b with
        // the respective a and b index
        if (a[size_a - 1] == b[size_b - 1])
        {
            index(dp, a, b, size_a - 1, size_b - 1);
            index_a.Add(size_a - 1);
            index_b.Add(size_b - 1);
        }
         
        else
        {
            if (dp[size_a - 1,size_b] > dp[size_a,
                                           size_b - 1])
            {
                index(dp, a, b, size_a - 1, size_b);
            }
            else
            {
                index(dp, a, b, size_a, size_b - 1);
            }
        }
    }
     
    // function to combine the strings to form
    // the shortest string
    static void combine(String a, String b,
                        int size_a,int size_b)
    {
        int[,] dp = new int[100, 100];
        String ans = "";
        int k = 0, i, j;
     
        // Store the increment of diagonally
        // previous value if a[i-1] and b[j-1] are
        // equal, else store the max of dp[i,j-1]
        // and dp[i-1,j]
        for (i = 1; i <= size_a; i++)
        {
            for (j = 1; j <= size_b; j++)
            {
                if (a[i-1] == b[j - 1])
                {
                    dp[i, j] = dp[i - 1, j - 1] + 1;
                }
                else
                {
                    dp[i, j] = Math.Max(dp[i, j - 1],
                                        dp[i - 1, j]);
                }
            }
        }
     
        // Get the Lowest Common Subsequence
        int lcs = dp[size_a, size_b];
     
        // Backtrack the dp array to get the index
        // vectors of two strings, used to find
        // the shortest possible combination.
        index(dp, a, b, size_a, size_b);
     
        i = j = k;
     
        // Build the string combination using the
        // index found by backtracking
        while (k < lcs)
        {
            while (i < size_a && i < index_a[k])
            {
                ans += a[i++];
            }
     
            while (j < size_b && j < index_b[k])
            {
                ans += b[j++];
            }
     
            ans = ans + a[index_a[k]];
            k++;
            i++;
            j++;
        }
     
        // Append the remaining characters in a
        // to answer
        while (i < size_a)
        {
            ans += a[i++];
        }
     
        // Append the remaining characters in b
        // to answer
        while (j < size_b)
        {
            ans += b[j++];
        }
     
        Console.WriteLine(ans);
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        String a = "algorithm";
        String b = "rhythm";
        combine(a, b, a.Length,b.Length);
    }
}
 
// This code is contributed by Princi Singh


输出:

algorihythm

基于LCS的解决方案:
我们使用LCS解决方案构建2D阵列。如果两个指针位置处的字符相等,则将长度增加1,否则将存储相邻位置中的最小值。最后,我们回溯矩阵以找到遍历索引向量,这将产生最短的组合。

C++

// C++ implementation to find shortest string for
// a combination of two strings
#include 
using namespace std;
 
// Vector that store the index of string a and b
vector index_a;
vector index_b;
 
// Subroutine to Backtrack the dp matrix to
// find the index vector traversing which would
// yield the shortest possible combination
void index(int dp[][100], string a, string b,
           int size_a, int size_b)
{
    // Clear the index vectors
    index_a.clear();
    index_b.clear();
 
    // Return if either of a or b is reduced
    // to 0
    if (size_a == 0 || size_b == 0)
        return;
 
    // Push both to index_a and index_b with
    // the respective a and b index
    if (a[size_a - 1] == b[size_b - 1]) {
        index(dp, a, b, size_a - 1, size_b - 1);
        index_a.push_back(size_a - 1);
        index_b.push_back(size_b - 1);
    } else {
        if (dp[size_a - 1][size_b] > dp[size_a]
                                    [size_b - 1]) {
            index(dp, a, b, size_a - 1, size_b);
        } else {
            index(dp, a, b, size_a, size_b - 1);
        }
    }
}
 
// function to combine the strings to form
// the shortest string
void combine(string a, string b, int size_a,
             int size_b)
{
 
    int dp[100][100];
    string ans = "";
    int k = 0;
 
    // Initialize the matrix to 0
    memset(dp, 0, sizeof(dp));
 
    // Store the increment of diagonally
    // previous value if a[i-1] and b[j-1] are
    // equal, else store the max of dp[i][j-1]
    // and dp[i-1][j]
    for (int i = 1; i <= size_a; i++) {
        for (int j = 1; j <= size_b; j++) {
            if (a[i - 1] == b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = max(dp[i][j - 1],
                               dp[i - 1][j]);
            }
        }
    }
 
    // Get the Lowest Common Subsequence
    int lcs = dp[size_a][size_b];
 
    // Backtrack the dp array to get the index
    // vectors of two strings, used to find
    // the shortest possible combination.
    index(dp, a, b, size_a, size_b);
 
    int i, j = i = k;
 
    // Build the string combination using the
    // index found by backtracking
    while (k < lcs) {
        while (i < size_a && i < index_a[k]) {
            ans += a[i++];
        }
 
        while (j < size_b && j < index_b[k]) {
            ans += b[j++];
        }
 
        ans = ans + a[index_a[k]];
        k++;
        i++;
        j++;
    }
 
    // Append the remaining characters in a
    // to answer
    while (i < size_a) {
        ans += a[i++];
    }
 
    // Append the remaining characters in b
    // to answer
    while (j < size_b) {
        ans += b[j++];
    }
 
    cout << ans;
}
 
// Driver code
int main()
{
    string a = "algorithm";
    string b = "rhythm";
 
    // Store the length of string
    int size_a = a.size();
    int size_b = b.size();
 
    combine(a, b, size_a, size_b);
    return 0;
}

Java

// Java implementation to find shortest string for
// a combination of two strings
import java.util.ArrayList;
public class GFG_2 {
          
    // Vector that store the index of string a and b
    static ArrayList index_a = new ArrayList<>();
    static ArrayList index_b = new ArrayList<>();
      
    // Subroutine to Backtrack the dp matrix to
    // find the index vector traversing which would
    // yield the shortest possible combination
    static void index(int dp[][], String a, String b,
               int size_a, int size_b)
    {
        // Clear the index vectors
        index_a.clear();
        index_b.clear();
      
        // Return if either of a or b is reduced
        // to 0
        if (size_a == 0 || size_b == 0)
            return;
      
        // Push both to index_a and index_b with
        // the respective a and b index
        if (a.charAt(size_a - 1) == b.charAt(size_b - 1)) {
            index(dp, a, b, size_a - 1, size_b - 1);
            index_a.add(size_a - 1);
            index_b.add(size_b - 1);
        } else {
            if (dp[size_a - 1][size_b] > dp[size_a]
                                        [size_b - 1]) {
                index(dp, a, b, size_a - 1, size_b);
            } else {
                index(dp, a, b, size_a, size_b - 1);
            }
        }
    }
      
    // function to combine the strings to form
    // the shortest string
    static void combine(String a, String b, int size_a,
                 int size_b)
    {
      
        int[][] dp = new int[100][100];
        String ans = "";
        int k = 0;
      
        // Store the increment of diagonally
        // previous value if a[i-1] and b[j-1] are
        // equal, else store the max of dp[i][j-1]
        // and dp[i-1][j]
        for (int i = 1; i <= size_a; i++) {
            for (int j = 1; j <= size_b; j++) {
                if (a.charAt(i - 1) == b.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j - 1],
                                   dp[i - 1][j]);
                }
            }
        }
      
        // Get the Lowest Common Subsequence
        int lcs = dp[size_a][size_b];
      
        // Backtrack the dp array to get the index
        // vectors of two strings, used to find
        // the shortest possible combination.
        index(dp, a, b, size_a, size_b);
      
        int i, j = i = k;
      
        // Build the string combination using the
        // index found by backtracking
        while (k < lcs) {
            while (i < size_a && i < index_a.get(k)) {
                ans += a.charAt(i++);
            }
      
            while (j < size_b && j < index_b.get(k)) {
                ans += b.charAt(j++);
            }
      
            ans = ans + a.charAt(index_a.get(k));
            k++;
            i++;
            j++;
        }
      
        // Append the remaining characters in a
        // to answer
        while (i < size_a) {
            ans += a.charAt(i++);
        }
      
        // Append the remaining characters in b
        // to answer
        while (j < size_b) {
            ans +=  b.charAt(j++);
        }
      
        System.out.println(ans);
    }
      
      
    /* Driver program to test above function */
    public static void main(String args[])
    {
      String a = "algorithm";
      String b = "rhythm";
      combine(a, b, a.length(),b.length());
       
    }
}
// This article is contributed by Sumit Ghosh

Python3

# Python implementation to find shortest string for
# a combination of two strings
index_a = []
index_b = []
 
def index(dp, a, b, size_a, size_b):
    if (size_a == 0 or size_b == 0):
        return
    if (a[size_a - 1] == b[size_b - 1]):
        index(dp, a, b, size_a - 1, size_b - 1)
        index_a.append(size_a - 1)
        index_b.append(size_b - 1)
    else:
        if(dp[size_a - 1][size_b] > dp[size_a][size_b - 1]):
            index(dp, a, b, size_a - 1, size_b)
        else:
            index(dp, a, b, size_a, size_b - 1)
     
def combine(a, b, size_a, size_b):
    dp = [[0 for i in range(100)] for j in range(100)]
    ans = ""
    k = 0
     
    for i in range(1, size_a + 1):
        for j in range(1, size_b + 1):
            if(a[i - 1] == b[j - 1]):
                dp[i][j] = dp[i - 1][j - 1] + 1
            else:
                dp[i][j] = max(dp[i][j - 1], dp[i - 1][j])
     
    lcs = dp[size_a][size_b]
    index(dp, a, b, size_a, size_b)
    j = i = k
    while (k < lcs):
        while (i < size_a and i < index_a[k]):
            ans += a[i];
            i += 1
        while (j < size_b and j < index_b[k]):
            ans += b[j]
            j += 1
        ans = ans + a[index_a[k]]
        k += 1
        i += 1
        j += 1
     
    while (i < size_a):
        ans += a[i]
        i += 1
    while (j < size_b):
        ans += b[j]
        j += 1
    print(ans)
 
# Driver code
a = "algorithm"
b = "rhythm"
size_a = len(a)
size_b = len(b)
combine(a, b, size_a, size_b)
 
# This code is contributed by avanitrachhadiya2155

C#

// C# implementation to find shortest string for
// a combination of two strings
using System;
using System.Collections.Generic;
 
class GFG
{
         
    // Vector that store the index of string a and b
    static List index_a = new List();
    static List index_b = new List();
     
    // Subroutine to Backtrack the dp matrix to
    // find the index vector traversing which would
    // yield the shortest possible combination
    static void index(int [,]dp, String a, String b,
                      int size_a, int size_b)
    {
        // Clear the index vectors
        index_a.Clear();
        index_b.Clear();
     
        // Return if either of a or b is reduced
        // to 0
        if (size_a == 0 || size_b == 0)
            return;
     
        // Push both to index_a and index_b with
        // the respective a and b index
        if (a[size_a - 1] == b[size_b - 1])
        {
            index(dp, a, b, size_a - 1, size_b - 1);
            index_a.Add(size_a - 1);
            index_b.Add(size_b - 1);
        }
         
        else
        {
            if (dp[size_a - 1,size_b] > dp[size_a,
                                           size_b - 1])
            {
                index(dp, a, b, size_a - 1, size_b);
            }
            else
            {
                index(dp, a, b, size_a, size_b - 1);
            }
        }
    }
     
    // function to combine the strings to form
    // the shortest string
    static void combine(String a, String b,
                        int size_a,int size_b)
    {
        int[,] dp = new int[100, 100];
        String ans = "";
        int k = 0, i, j;
     
        // Store the increment of diagonally
        // previous value if a[i-1] and b[j-1] are
        // equal, else store the max of dp[i,j-1]
        // and dp[i-1,j]
        for (i = 1; i <= size_a; i++)
        {
            for (j = 1; j <= size_b; j++)
            {
                if (a[i-1] == b[j - 1])
                {
                    dp[i, j] = dp[i - 1, j - 1] + 1;
                }
                else
                {
                    dp[i, j] = Math.Max(dp[i, j - 1],
                                        dp[i - 1, j]);
                }
            }
        }
     
        // Get the Lowest Common Subsequence
        int lcs = dp[size_a, size_b];
     
        // Backtrack the dp array to get the index
        // vectors of two strings, used to find
        // the shortest possible combination.
        index(dp, a, b, size_a, size_b);
     
        i = j = k;
     
        // Build the string combination using the
        // index found by backtracking
        while (k < lcs)
        {
            while (i < size_a && i < index_a[k])
            {
                ans += a[i++];
            }
     
            while (j < size_b && j < index_b[k])
            {
                ans += b[j++];
            }
     
            ans = ans + a[index_a[k]];
            k++;
            i++;
            j++;
        }
     
        // Append the remaining characters in a
        // to answer
        while (i < size_a)
        {
            ans += a[i++];
        }
     
        // Append the remaining characters in b
        // to answer
        while (j < size_b)
        {
            ans += b[j++];
        }
     
        Console.WriteLine(ans);
    }
     
    // Driver Code
    public static void Main(String []args)
    {
        String a = "algorithm";
        String b = "rhythm";
        combine(a, b, a.Length,b.Length);
    }
}
 
// This code is contributed by Princi Singh

输出:

algorihythm