📌  相关文章
📜  找到一个字符串的最长子序列,它是另一个字符串的子字符串

📅  最后修改于: 2021-09-17 16:14:36             🧑  作者: Mango

给定两个由NM 个字符组成的字符串XY ,任务是找到字符串X的最长子序列,它是字符串Y的子字符串。

例子:

朴素方法:解决给定问题的最简单方法是找到给定字符串X 的所有子序列,并在所有生成的子序列中打印该子序列,该子序列是最大长度且是Y的子字符串。

时间复杂度: O(N*M*2 N )
辅助空间: O(N)

高效的方法:上述方法也可以通过使用动态规划进行优化。我们的想法是创建一个二维数组,DP [] []的尺寸(N + 1)*(M + 1)和状态DP[i] [j]X [0,1]的子序列的最大长度,其是Y[0, j] 的子串。请按照以下步骤解决问题:

  • 创建一个大小为N+1行和M+1列的二维数组dp[][]
  • 0初始化矩阵的第一行和第一列。
  • 按如下方式填充所有剩余的行:
    • 如果X[i – 1]的值等于Y[j – 1]的值,则将dp[i][j]的值更新为(1 + dp[i – 1][j – 1] )
    • 否则,将dp[i][j]的值更新为dp[i – 1][j]
  • 通过迭代矩阵中的最后一行,将所需序列的最大长度存储在变量len 中,并将最大单元格值的行和列索引分别存储在变量ij 中
  • 创建一个变量,比如res来存储结果字符串并从最大单元格值回溯。
  • 迭代直到len的值大于0 ,执行以下步骤:
    • 如果X[i – 1]的值等于Y[j – 1] 的值,则将X[i – 1]附加到res并将lenij的值减 1。
    • 否则,将i的值减 1。
  • 完成上述步骤后,打印字符串res作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the longest
// subsequence that matches with
// the substring of other string
string longestSubsequence(string X, string Y)
{
     
    // Stores the lengths of strings
    // X and Y
    int n = X.size();
    int m = Y.size();
 
    // Create a matrix
    vector> mat(n + 1, vector(m + 1));
     
    // Initialize the matrix
    for(int i = 0; i < n + 1; i++)
    {
        for(int j = 0; j < m + 1; j++)
        {
            if (i == 0 || j == 0)
                mat[i][j] = 0;
        }
    }
 
    // Fill all the remaining rows
    for(int i = 1; i < n + 1; i++)
    {
        for(int j = 1; j < m + 1; j++)
        {
             
            // If the characters are equal
            if (X[i - 1] == Y[j - 1])
            {
                mat[i][j] = 1 + mat[i - 1][j - 1];
            }
 
            // If not equal, then
            // just move to next
            // in subsequence string
            else
            {
                mat[i][j] = mat[i - 1][j];
            }
        }
    }
 
    // Find maximum length of the
    // longest subsequence matching
    // substring of other string
    int len = 0, col = 0;
 
    // Iterate through the last
    // row of matrix
    for(int i = 0; i < m + 1; i++)
    {
        if (mat[n][i] > len)
        {
            len = mat[n][i];
            col = i;
        }
    }
 
    // Store the required string
    string res = "";
    int i = n;
    int j = col;
 
    // Backtrack from the cell
    while (len > 0)
    {
         
        // If equal, then add the
        // character to res string
        if (X[i - 1] == Y[j - 1])
        {
            res = X[i - 1] + res;
            i--;
            j--;
            len--;
        }
        else
        {
            i--;
        }
    }
 
    // Return the required string
    return res;
}
 
// Driver code
int main()
{
    string X = "ABCD";
    string Y = "ACDBDCD";
     
    cout << (longestSubsequence(X, Y));
     
    return 0;
}
 
// This code is contributed by mohit kumar 29


Java
// Java program for the above approach
 
class GFG {
 
    // Function to find the longest
    // subsequence that matches with
    // the substring of other string
    public static String longestSubsequence(
        String X, String Y)
    {
 
        // Stores the lengths of strings
        // X and Y
        int n = X.length();
        int m = Y.length();
 
        // Create a matrix
        int[][] mat = new int[n + 1][m + 1];
 
        // Initialize the matrix
        for (int i = 0; i < n + 1; i++) {
            for (int j = 0; j < m + 1; j++) {
                if (i == 0 || j == 0)
                    mat[i][j] = 0;
            }
        }
 
        // Fill all the remaining rows
        for (int i = 1;
             i < n + 1; i++) {
 
            for (int j = 1;
                 j < m + 1; j++) {
 
                // If the characters are equal
                if (X.charAt(i - 1)
                    == Y.charAt(j - 1)) {
                    mat[i][j] = 1
                                + mat[i - 1][j - 1];
                }
 
                // If not equal, then
                // just move to next
                // in subsequence string
                else {
                    mat[i][j] = mat[i - 1][j];
                }
            }
        }
 
        // Find maximum length of the
        // longest subsequence matching
        // substring of other string
        int len = 0, col = 0;
 
        // Iterate through the last
        // row of matrix
        for (int i = 0; i < m + 1; i++) {
 
            if (mat[n][i] > len) {
                len = mat[n][i];
                col = i;
            }
        }
 
        // Store the required string
        String res = "";
        int i = n;
        int j = col;
 
        // Backtrack from the cell
        while (len > 0) {
 
            // If equal, then add the
            // character to res string
            if (X.charAt(i - 1)
                == Y.charAt(j - 1)) {
 
                res = X.charAt(i - 1) + res;
                i--;
                j--;
                len--;
            }
            else {
                i--;
            }
        }
 
        // Return the required string
        return res;
    }
 
    // Driver Code
    public static void main(String args[])
    {
        String X = "ABCD";
        String Y = "ACDBDCD";
        System.out.println(
            longestSubsequence(X, Y));
    }
}


Python3
# Python3 program for the above approach
 
# Function to find the longest
# subsequence that matches with
# the substring of other string
def longestSubsequence(X, Y):
     
    # Stores the lengths of strings
    # X and Y
    n = len(X)
    m = len(Y)
 
    # Create a matrix
    mat = [[0 for i in range(m + 1)]
              for j in range(n + 1)]
               
    # Initialize the matrix
    for i in range(0, n + 1):
        for j in range(0, m + 1):
            if (i == 0 or j == 0):
                mat[i][j] = 0
 
    # Fill all the remaining rows
    for i in range(1, n + 1):
        for j in range(1, m + 1):
             
            # If the characters are equal
            if (X[i - 1] == Y[j - 1]):
                mat[i][j] = 1 + mat[i - 1][j - 1]
                 
            # If not equal, then
            # just move to next
            # in subsequence string
            else:
                mat[i][j] = mat[i - 1][j]
 
    # Find maximum length of the
    # longest subsequence matching
    # substring of other string
    len1 = 0
    col = 0
     
    # Iterate through the last
    # row of matrix
    for i in range(0, m + 1):
        if (mat[n][i] > len1):
            len1 = mat[n][i]
            col = i
 
    # Store the required string
    res = ""
    i = n
    j = col
     
    # Backtrack from the cell
    while (len1 > 0):
 
        # If equal, then add the
        # character to res string
        if (X[i - 1] == Y[j - 1]):
            res = X[i - 1] + res
            i -= 1
            j -= 1
            len1 -= 1
        else:
            i -= 1
 
    # Return the required string
    return res
 
# Driver code
X = "ABCD"
Y = "ACDBDCD"
 
print(longestSubsequence(X, Y))
 
# This code is contributed by amreshkumar3


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find the longest
// subsequence that matches with
// the substring of other string
static string longestSubsequence(string X, string Y)
{
    int i, j;
     
    // Stores the lengths of strings
    // X and Y
    int n = X.Length;
    int m = Y.Length;
 
    // Create a matrix
    int [,]mat = new int[n + 1, m + 1];
 
    // Initialize the matrix
    for(i = 0; i < n + 1; i++)
    {
        for(j = 0; j < m + 1; j++)
        {
            if (i == 0 || j == 0)
                mat[i,j] = 0;
        }
    }
 
    // Fill all the remaining rows
    for(i = 1; i < n + 1; i++)
    {
        for(j = 1; j < m + 1; j++)
        {
             
            // If the characters are equal
            if (X[i - 1] == Y[j - 1])
            {
                mat[i, j] = 1 + mat[i - 1, j - 1];
            }
 
            // If not equal, then
            // just move to next
            // in subsequence string
            else
            {
                mat[i, j] = mat[i - 1, j];
            }
        }
    }
 
    // Find maximum length of the
    // longest subsequence matching
    // substring of other string
    int len = 0, col = 0;
 
    // Iterate through the last
    // row of matrix
    for(i = 0; i < m + 1; i++)
    {
        if (mat[n,i] > len)
        {
            len = mat[n,i];
            col = i;
        }
    }
 
    // Store the required string
    string res = "";
    i = n;
    j = col;
 
    // Backtrack from the cell
    while (len > 0)
    {
         
        // If equal, then add the
        // character to res string
        if (X[i - 1] == Y[j - 1])
        {
            res = X[i - 1] + res;
            i--;
            j--;
            len--;
        }
        else
        {
            i--;
        }
    }
 
    // Return the required string
    return res;
}
 
// Driver Code
public static void Main()
{
    string X = "ABCD";
    string Y = "ACDBDCD";
     
    Console.Write(longestSubsequence(X, Y));
}
}
 
// This code is contributed by bgangwar59


Javascript


输出:
ACD

时间复杂度: O(N*M)
辅助空间: O(N*M)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程