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个字符串X , Y和Z ,任务是在所有三个给定序列中找到最长的公共子序列 。
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
给定输入是三个字符串N , M , K的长度,然后在接下来的几行分别是字符串X , Y , Z本身
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”
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
如果它们不相似,我们最多需要找到三种情况
Leave X[i] recur for others
将X [i]留给他人重复
Leave Y[j] recur for others
离开Y [j]为其他人重复
Leave Z[k] recur for others
将Z [k]留给其他人重复
So, if we formulate the above idea in to our recursion function then
因此,如果我们将上述想法表达为递归函数,则
f(N-1,M,K) = Leave X[i] recur for others
f(N-1,M,K) =让X [i]重复出现
f(N,M-1,K) = Leave Y[j] recur for others
f(N,M-1,K) =让Y [j]重复出现
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。
Initialize the dp table, dp[M+1][N+1][K+1]
初始化dp表dp [M + 1] [N + 1] [K + 1]
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
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