如何显示两个子字符串中最长公共子字符串的所有子字符串 我知道计算lcs长度的dp方法 但如何显示所有这些lcs lcs的代码
function LCSLength(X[1..m], Y[1..n])
C = array(0..m, 0..n)
for i := 0..m
C[i,0] = 0
for j := 0..n
C[0,j] = 0
for i := 1..m
for j := 1..n
if X[i] = Y[j]
C[i,j] := C[i-1,j-1] + 1
else
C[i,j] := max(C[i,j-1], C[i-1,j])
return C[m,n]
我无法在网上找到一篇关于如何找到所有lcs的好文章
string 1 = abcabcaa string 2 = acbacba
所有lcs
巴 蕉麻 ABCBA acaba ACACA acbaa ACBCA
我已经知道计算lcs的dp方法了 任何帮助将不胜感激
我在维基上发现了这个
function backtrackAll(C[0..m,0..n], X[1..m], Y[1..n], i, j)
if i = 0 or j = 0
return {""}
else if X[i] = Y[j]
return {Z + X[i] for all Z in backtrackAll(C, X, Y, i-1, j-1)}
else
R := {}
if C[i,j-1] ≥ C[i-1,j]
R := backtrackAll(C, X, Y, i, j-1)
if C[i-1,j] ≥ C[i,j-1]
R := R ∪ backtrackAll(C, X, Y, i-1, j)
return R
但是我很难理解它
答案 0 :(得分:2)
一种非常直观的方法是存储额外的2D阵列背景,即:
BP[i,j] := [(i-1,j-1)] if C[i,j] was created from C[i-1,j-1] (there was a match)
BP[i,j] := [(i,j-1), (i-1,j)] if C[i,j] could came from C[i,j-1] or C[i-1,j]
BP[i,j] := [(i,j-1)] if C[i,j] was created from C[i,j-1]
BP[i,j] := [(i-1,j)] if C[i,j] was created from C[i-1,j]
现在,让我们定义一个有向图。数组C中的任何条目[i,j]
对应于顶点,后背对应于边。
有n*m
个顶点和最多2*n*m
个边,因为一个顶点最多有2个后投影。
现在的问题是将此图中的所有路径从顶点[n,m]
返回到顶点[0,0]
。
图表是定向的,没有周期,因此您可以简单地按照DFS指示(不将顶点标记为已访问),并且对于每个边([i,j] -> [i-1,j-1])
,将与此匹配对应的字母附加到结果串。 LCS是在到达[0,0]
顶点后累积的字符串。
答案 1 :(得分:0)
这是LCS最简单的java程序: -
import java.util.Scanner;
public class StrCmp {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter the string");
String s1=s.nextLine();
String s2=s.nextLine();
String temp = "";
char[] a = s1.toCharArray();
char[] b= s2.toCharArray();
for(int i=0;i<a.length;i++)
{
for(int j=0;j<b.length;j++)
{
if(s1.charAt(i)==s2.charAt(j))
{
if(temp.contains(String.valueOf(s2.charAt(j)))){
break;
}
temp = temp + s2.charAt(j);
}
}
}
System.out.println(temp);
}
}
答案 2 :(得分:-1)
每个c [i,j]条目仅取决于其他三个c表条目:c [i-1,j-1],c [i-1,j], 和c [i,j-1]。给定c [i,j]的值,我们可以在O(1)时间中确定哪个 这三个值用于计算c [i,j]。当前3个点存在多个可能值时,可能存在不同的值,即它们在同一点上相同且最高。然后你必须考虑它们中的每一个。