按字典顺序打印所有最长的公共子序列

你有两条线。现在你必须按字典顺序打印所有最长的公共子序列? 例如:

null
Input : str1 = "abcabcaa", str2 = "acbacba"Output: ababa        abaca        abcba        acaba        acaca        acbaa        acbca

这个问题是问题的延伸 最长公共子序列 我们首先找到LCS的长度,并使用记忆(或动态编程)将所有LCS存储在2D表格中。然后我们搜索两个字符串中从“a”到“z”(输出排序顺序)的所有字符。如果在字符串中发现一个字符,并且字符的当前位置导致LCS,我们递归搜索所有出现的字符,当前LCS长度加1。 下面是算法的实现。

C++

// C++ program to find all LCS of two strings in
// sorted order.
#include<bits/stdc++.h>
#define MAX 100
using namespace std;
// length of lcs
int lcslen = 0;
// dp matrix to store result of sub calls for lcs
int dp[MAX][MAX];
// A memoization based function that returns LCS of
// str1[i..len1-1] and str2[j..len2-1]
int lcs(string str1, string str2, int len1, int len2,
int i, int j)
{
int &ret = dp[i][j];
// base condition
if (i==len1 || j==len2)
return ret = 0;
// if lcs has been computed
if (ret != -1)
return ret;
ret = 0;
// if characters are same return previous + 1 else
// max of two sequences after removing i'th and j'th
// char one by one
if (str1[i] == str2[j])
ret = 1 + lcs(str1, str2, len1, len2, i+1, j+1);
else
ret = max(lcs(str1, str2, len1, len2, i+1, j),
lcs(str1, str2, len1, len2, i, j+1));
return ret;
}
// Function to print all routes common sub-sequences of
// length lcslen
void printAll(string str1, string str2, int len1, int len2,
char data[], int indx1, int indx2, int currlcs)
{
// if currlcs is equal to lcslen then print it
if (currlcs == lcslen)
{
data[currlcs] = ' ' ;
puts (data);
return ;
}
// if we are done with all the characters of both string
if (indx1==len1 || indx2==len2)
return ;
// here we have to print all sub-sequences lexicographically,
// that's why we start from 'a'to'z' if this character is
// present in both of them then append it in data[] and same
// remaining part
for ( char ch= 'a' ; ch<= 'z' ; ch++)
{
// done is a flag to tell that we have printed all the
// subsequences corresponding to current character
bool done = false ;
for ( int i=indx1; i<len1; i++)
{
// if character ch is present in str1 then check if
// it is present in str2
if (ch==str1[i])
{
for ( int j=indx2; j<len2; j++)
{
// if ch is present in both of them and
// remaining length is equal to remaining
// lcs length then add ch in sub-sequence
if (ch==str2[j] &&
dp[i][j] == lcslen-currlcs)
{
data[currlcs] = ch;
printAll(str1, str2, len1, len2, data, i+1, j+1, currlcs+1);
done = true ;
break ;
}
}
}
// If we found LCS beginning with current character.
if (done)
break ;
}
}
}
// This function prints all LCS of str1 and str2
// in lexicographic order.
void prinlAllLCSSorted(string str1, string str2)
{
// Find lengths of both strings
int len1 = str1.length(), len2 = str2.length();
// Find length of LCS
memset (dp, -1, sizeof (dp));
lcslen = lcs(str1, str2, len1, len2, 0, 0);
// Print all LCS using recursive backtracking
// data[] is used to store individual LCS.
char data[MAX];
printAll(str1, str2, len1, len2, data, 0, 0, 0);
}
// Driver program to run the case
int main()
{
string str1 = "abcabcaa" , str2 = "acbacba" ;
prinlAllLCSSorted(str1, str2);
return 0;
}


JAVA

// Java program to find all LCS of two strings in
// sorted order.
class GFG
{
static int MAX = 100 ;
// length of lcs
static int lcslen = 0 ;
// dp matrix to store result of sub calls for lcs
static int [][] dp = new int [MAX][MAX];
// A memoization based function that returns LCS of
// str1[i..len1-1] and str2[j..len2-1]
static int lcs(String str1, String str2,
int len1, int len2, int i, int j)
{
int ret = dp[i][j];
// base condition
if (i == len1 || j == len2)
return ret = 0 ;
// if lcs has been computed
if (ret != - 1 )
return ret;
ret = 0 ;
// if characters are same return previous + 1 else
// max of two sequences after removing i'th and j'th
// char one by one
if (str1.charAt(i) == str2.charAt(j))
ret = 1 + lcs(str1, str2, len1, len2, i + 1 , j + 1 );
else
ret = Math.max(lcs(str1, str2, len1, len2, i + 1 , j),
lcs(str1, str2, len1, len2, i, j + 1 ));
return ret;
}
// Function to print all routes common sub-sequences of
// length lcslen
static void printAll(String str1, String str2, int len1, int len2,
char [] data, int indx1, int indx2, int currlcs)
{
// if currlcs is equal to lcslen then print it
if (currlcs == lcslen)
{
data[currlcs] = ' ' ;
System.out.println( new String(data));
return ;
}
// if we are done with all the characters of both string
if (indx1 == len1 || indx2 == len2)
return ;
// here we have to print all sub-sequences lexicographically,
// that's why we start from 'a'to'z' if this character is
// present in both of them then append it in data[] and same
// remaining part
for ( char ch = 'a' ; ch <= 'z' ; ch++)
{
// done is a flag to tell that we have printed all the
// subsequences corresponding to current character
boolean done = false ;
for ( int i = indx1; i < len1; i++)
{
// if character ch is present in str1 then check if
// it is present in str2
if (ch == str1.charAt(i))
{
for ( int j = indx2; j < len2; j++)
{
// if ch is present in both of them and
// remaining length is equal to remaining
// lcs length then add ch in sub-sequence
if (ch == str2.charAt(j) &&
dp[i][j] == lcslen - currlcs)
{
data[currlcs] = ch;
printAll(str1, str2, len1, len2,
data, i + 1 , j + 1 , currlcs + 1 );
done = true ;
break ;
}
}
}
// If we found LCS beginning with current character.
if (done)
break ;
}
}
}
// This function prints all LCS of str1 and str2
// in lexicographic order.
static void prinlAllLCSSorted(String str1, String str2)
{
// Find lengths of both strings
int len1 = str1.length(), len2 = str2.length();
// Find length of LCS
for ( int i = 0 ; i < MAX; i++)
{
for ( int j = 0 ; j < MAX; j++)
{
dp[i][j] = - 1 ;
}
}
lcslen = lcs(str1, str2, len1, len2, 0 , 0 );
// Print all LCS using recursive backtracking
// data[] is used to store individual LCS.
char [] data = new char [MAX];
printAll(str1, str2, len1, len2, data, 0 , 0 , 0 );
}
// Driver code
public static void main(String[] args)
{
String str1 = "abcabcaa" , str2 = "acbacba" ;
prinlAllLCSSorted(str1, str2);
}
}
// This code is contributed by divyesh072019


Python3

# Python3 program to find all LCS of two strings in
# sorted order.
MAX = 100
lcslen = 0
# dp matrix to store result of sub calls for lcs
dp = [[ - 1 for i in range ( MAX )] for i in range ( MAX )]
# A memoization based function that returns LCS of
# str1[i..len1-1] and str2[j..len2-1]
def lcs(str1, str2, len1, len2, i, j):
# base condition
if (i = = len1 or j = = len2):
dp[i][j] = 0
return dp[i][j]
# if lcs has been computed
if (dp[i][j] ! = - 1 ):
return dp[i][j]
ret = 0
# if characters are same return previous + 1 else
# max of two sequences after removing i'th and j'th
# char one by one
if (str1[i] = = str2[j]):
ret = 1 + lcs(str1, str2, len1, len2, i + 1 , j + 1 )
else :
ret = max (lcs(str1, str2, len1, len2, i + 1 , j),
lcs(str1, str2, len1, len2, i, j + 1 ))
dp[i][j] = ret
return ret
# Function to print all routes common sub-sequences of
# length lcslen
def printAll(str1, str2, len1, len2,data, indx1, indx2, currlcs):
# if currlcs is equal to lcslen then print
if (currlcs = = lcslen):
print ("".join(data[:currlcs]))
return
# if we are done with all the characters of both string
if (indx1 = = len1 or indx2 = = len2):
return
# here we have to print all sub-sequences lexicographically,
# that's why we start from 'a'to'z' if this character is
# present in both of them then append it in data[] and same
# remaining part
for ch in range ( ord ( 'a' ), ord ( 'z' ) + 1 ):
# done is a flag to tell that we have printed all the
# subsequences corresponding to current character
done = False
for i in range (indx1,len1):
# if character ch is present in str1 then check if
# it is present in str2
if ( chr (ch) = = str1[i]):
for j in range (indx2, len2):
# if ch is present in both of them and
# remaining length is equal to remaining
# lcs length then add ch in sub-sequence
if ( chr (ch) = = str2[j] and dp[i][j] = = lcslen - currlcs):
data[currlcs] = chr (ch)
printAll(str1, str2, len1, len2, data, i + 1 , j + 1 , currlcs + 1 )
done = True
break
# If we found LCS beginning with current character.
if (done):
break
# This function prints all LCS of str1 and str2
# in lexicographic order.
def prinlAllLCSSorted(str1, str2):
global lcslen
# Find lengths of both strings
len1,len2 = len (str1), len (str2)
lcslen = lcs(str1, str2, len1, len2, 0 , 0 )
# Print all LCS using recursive backtracking
# data[] is used to store individual LCS.
data = [ 'a' for i in range ( MAX )]
printAll(str1, str2, len1, len2, data, 0 , 0 , 0 )
# Driver program to run the case
if __name__ = = '__main__' :
str1 = "abcabcaa"
str2 = "acbacba"
prinlAllLCSSorted(str1, str2)
# This code is contributed by mohit kumar 29


C#

// C# program to find all LCS of two strings in
// sorted order.
using System;
class GFG
{
static int MAX = 100;
// length of lcs
static int lcslen = 0;
// dp matrix to store result of sub calls for lcs
static int [,] dp = new int [MAX,MAX];
// A memoization based function that returns LCS of
// str1[i..len1-1] and str2[j..len2-1]
static int lcs( string str1, string str2,
int len1, int len2, int i, int j)
{
int ret = dp[i, j];
// base condition
if (i == len1 || j == len2)
return ret = 0;
// if lcs has been computed
if (ret != -1)
return ret;
ret = 0;
// if characters are same return previous + 1 else
// max of two sequences after removing i'th and j'th
// char one by one
if (str1[i] == str2[j])
ret = 1 + lcs(str1, str2, len1, len2, i + 1, j + 1);
else
ret = Math.Max(lcs(str1, str2, len1, len2, i + 1, j),
lcs(str1, str2, len1, len2, i, j + 1));
return ret;
}
// Function to print all routes common sub-sequences of
// length lcslen
static void printAll( string str1, string str2, int len1, int len2,
char [] data, int indx1, int indx2, int currlcs)
{
// if currlcs is equal to lcslen then print it
if (currlcs == lcslen)
{
data[currlcs] = ' ' ;
Console.WriteLine( new string (data));
return ;
}
// if we are done with all the characters of both string
if (indx1 == len1 || indx2 == len2)
return ;
// here we have to print all sub-sequences lexicographically,
// that's why we start from 'a'to'z' if this character is
// present in both of them then append it in data[] and same
// remaining part
for ( char ch= 'a' ; ch<= 'z' ; ch++)
{
// done is a flag to tell that we have printed all the
// subsequences corresponding to current character
bool done = false ;
for ( int i = indx1; i < len1; i++)
{
// if character ch is present in str1 then check if
// it is present in str2
if (ch == str1[i])
{
for ( int j = indx2; j < len2; j++)
{
// if ch is present in both of them and
// remaining length is equal to remaining
// lcs length then add ch in sub-sequence
if (ch == str2[j] &&
lcs(str1, str2, len1, len2, i, j) == lcslen-currlcs)
{
data[currlcs] = ch;
printAll(str1, str2, len1, len2, data, i+1, j+1, currlcs+1);
done = true ;
break ;
}
}
}
// If we found LCS beginning with current character.
if (done)
break ;
}
}
}
// This function prints all LCS of str1 and str2
// in lexicographic order.
static void prinlAllLCSSorted( string str1, string str2)
{
// Find lengths of both strings
int len1 = str1.Length, len2 = str2.Length;
// Find length of LCS
for ( int i = 0; i < MAX; i++)
{
for ( int j = 0; j < MAX; j++)
{
dp[i, j] = -1;
}
}
lcslen = lcs(str1, str2, len1, len2, 0, 0);
// Print all LCS using recursive backtracking
// data[] is used to store individual LCS.
char [] data = new char [MAX];
printAll(str1, str2, len1, len2, data, 0, 0, 0);
}
// Driver code
static void Main()
{
string str1 = "abcabcaa" , str2 = "acbacba" ;
prinlAllLCSSorted(str1, str2);
}
}
// This code is contributed by divyeshrabadiya07


Javascript

<script>
// Javascript program to find all LCS of two strings in
// sorted order.
let  MAX = 100;
// length of lcs
let lcslen = 0;
// dp matrix to store result of sub calls for lcs
let dp = new Array(MAX);
// A memoization based function that returns LCS of
// str1[i..len1-1] and str2[j..len2-1]
function lcs(str1,str2,len1,len2,i,j)
{
let ret = dp[i][j];
// base condition
if (i == len1 || j == len2)
return ret = 0;
// if lcs has been computed
if (ret != -1)
return ret;
ret = 0;
// if characters are same return previous + 1 else
// max of two sequences after removing i'th and j'th
// char one by one
if (str1[i] == str2[j])
ret = 1 + lcs(str1, str2, len1, len2, i + 1, j + 1);
else
ret = Math.max(lcs(str1, str2, len1, len2, i + 1, j),
lcs(str1, str2, len1, len2, i, j + 1));
return ret;
}
// Function to print all routes common sub-sequences of
// length lcslen
function printAll(str1,str2,len1,len2,data,indx1,indx2,currlcs)
{
// if currlcs is equal to lcslen then print it
if (currlcs == lcslen)
{
data[currlcs] = null ;
document.write(data.join( "" )+ "<br>" );
return ;
}
// if we are done with all the characters of both string
if (indx1 == len1 || indx2 == len2)
return ;
// here we have to print all sub-sequences lexicographically,
// that's why we start from 'a'to'z' if this character is
// present in both of them then append it in data[] and same
// remaining part
for (let ch ='a '.charCodeAt(0); ch <=' z'.charCodeAt(0); ch++)
{
// done is a flag to tell that we have printed all the
// subsequences corresponding to current character
let done = false ;
for (let i = indx1; i < len1; i++)
{
// if character ch is present in str1 then check if
// it is present in str2
if (ch == str1[i].charCodeAt(0))
{
for (let j = indx2; j < len2; j++)
{
// if ch is present in both of them and
// remaining length is equal to remaining
// lcs length then add ch in sub-sequence
if (ch == str2[j].charCodeAt(0) &&
lcs(str1, str2, len1, len2, i, j) == lcslen - currlcs)
{
data[currlcs] = String.fromCharCode(ch);
printAll(str1, str2, len1, len2,
data, i + 1, j + 1, currlcs + 1);
done = true ;
break ;
}
}
}
// If we found LCS beginning with current character.
if (done)
break ;
}
}
}
// This function prints all LCS of str1 and str2
// in lexicographic order.
function prinlAllLCSSorted(str1,str2)
{
// Find lengths of both strings
let len1 = str1.length, len2 = str2.length;
// Find length of LCS
for (let i = 0; i < MAX; i++)
{
dp[i]= new Array(MAX);
for (let j = 0; j < MAX; j++)
{
dp[i][j] = -1;
}
}
lcslen = lcs(str1, str2, len1, len2, 0, 0);
// Print all LCS using recursive backtracking
// data[] is used to store individual LCS.
let data = new Array(MAX);
printAll(str1, str2, len1, len2, data, 0, 0, 0);
}
// Driver code
let str1 = "abcabcaa" , str2 = "acbacba" ;
prinlAllLCSSorted(str1, str2);
// This code is contributed by unknown2108
</script>


输出

ababaabacaabcbaacabaacacaacbaaacbca

本文由 沙克·米什拉(古卢) .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享