三弦的最长公共子序列

Problem statement:

问题陈述:

Given 3 strings X, Y and Z, the task is to find the longest common sub-sequence in all three given sequences.

给定3个字符串XYZ ,任务是在所有三个给定序列中找到最长的公共子序列

Input:

输入:

Given input is the length of three string N, M, K and then in the next lines the strings X, Y, Z themselves respectively

给定输入是三个字符串NMK的长度,然后在接下来的几行分别是字符串XYZ本身

Output:

输出:

Print the length of the longest common sub- sequence of the three strings

打印三个字符串中最长的公共子序列的长度

Constraints:

限制条件:

1<= N, M, K <=100

Example:

例:

Input:
N = 5, M = 6, K = 7

X = "inclu"
Y = "socluue"
Z = "anyclue"

Output:
The length of longest common subsequence for these three strings are 3

Explanation:

说明:

The longest common subsequence for these three strings is:

这三个字符串的最长公共子序列是:

"clu" which is of length 3

长度为3的“ clu”

Longest Common Subsequence of three strings (1)

Solution Approach:

解决方法:

We need a 3D table to store the computed values.

我们需要一个3D表来存储计算值。

Let's say for sub-sequences,

比方说子序列,

X[1...i] i < N
Y[1...j] j < M
Z[1...k] k < K

Now if X[i]==Y[j]==Z[k] then surely, we found a character which is common and we need to recur for the remaining ones

现在,如果X [i] == Y [j] == Z [k],那么我们肯定找到了一个常见的字符,我们需要重复其余的字符

If they are not similar, we need to find maximum of three cases

如果它们不相似,我们最多需要找到三种情况

  1. Leave X[i] recur for others

    X [i]留给他人重复

  2. Leave Y[j] recur for others

    离开Y [j]为其他人重复

  3. Leave Z[k] recur for others

    Z [k]留给其他人重复

So, if we formulate the above idea in to our recursion function then

因此,如果我们将上述想法表达为递归函数,则

Longest Common Subsequence of three strings (0)
  1. f(N-1,M,K) = Leave X[i] recur for others

    f(N-1,M,K) =让X [i]重复出现

  2. f(N,M-1,K) = Leave Y[j] recur for others

    f(N,M-1,K) =让Y [j]重复出现

  3. f(N,M,K-1) = Leave Z[k] recur for others

    f(N,M,K-1) =让Z [k]重复出现

Now, the above recursion will result to many overlapping sub problems. Hence, we need to convert the above to DP.

现在,以上递归将导致许多重叠的子问题。 因此,我们需要将以上内容转换为DP。

  1. Initialize the dp table, dp[M+1][N+1][K+1]

    初始化dp表dp [M + 1] [N + 1] [K + 1]

  2. Fill the base cases,

    填写基本案例,

    for i=0 to M
        for j=0 to N
            dp[i][j][0]=0;
        end for
    end for
    for i=0 to N
        for j=0 to K 
            dp[0][i][j]=0;
        end for
    end for
    for i=0 to M
        for j=0 to K
            dp[i][0][j]=0;
        end for
    end for
    
    
  3. Fill up the other values,

    填写其他值,

    for i=1 to M
        for j=1 to N
            for k=1 to K
                if(s1[i-1]==s2[j-1] && s2[j-1]==s3[k-1])
                    dp[i][j][k]=1+dp[i-1][j-1][k-1];
                else
                    dp[i][j][k]=max(dp[i-1][j][k],dp[i][j-1][k],dp[i][j][k-1]);
                end for
        end for
    end for
    
    

Obviously, visual illustration for the 3D DP calculation is not possible, but you can go through the computation for LCS between two strings to understand how this 3D table is being filled.

显然,无法进行3D DP计算的直观图示,但是您可以在两个字符串之间进行LCS的计算,以了解如何填充此3D表。

C++ Implementation:

C ++实现:

#include <bits/stdc++.h>
using namespace std;

int max(int a, int b, int c)
{

    if (a > b && a > c)
        return a;
    if (b > c)
        return b;
    return c;
}

int LCS3(string s1, string s2, string s3, int m, int n, int o)
{

    int dp[m + 1][n + 1][o + 1];

    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            dp[i][j][0] = 0;
        }
    }
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= o; j++) {
            dp[0][i][j] = 0;
        }
    }
    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= o; j++) {
            dp[i][0][j] = 0;
        }
    }

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            for (int k = 1; k <= o; k++) {
                if (s1[i - 1] == s2[j - 1] && s2[j - 1] == s3[k - 1]) {
                    dp[i][j][k] = 1 + dp[i - 1][j - 1][k - 1];
                }
                else {
                    dp[i][j][k] = max(dp[i - 1][j][k], dp[i][j - 1][k], dp[i][j][k - 1]);
                }
            }
        }
    }
    return dp[m][n][o];
}

int main()
{
    int t, m, n, o;

    cout << "enter length of three strings respectively\n";
    cin >> m >> n >> o;

    cout << "enter the three strings respectively\n";
    string s1, s2, s3;
    cin >> s1 >> s2 >> s3;

    cout << "length of LCS of the three is : " << LCS3(s1, s2, s3, m, n, o) << endl;

    return 0;
}

Output:

输出:

enter length of three strings respectively
5 6 7
enter the three strings respectively
inclu
socluu
anyclue
length of LCS of the three is : 3


翻译自: https://www.includehelp.com/icp/longest-common-subsequence-of-three-strings.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值