最长的公共子序列打印所有子序列

时间:2013-08-28 19:30:21

标签: algorithm tree lcs

如何显示两个子字符串中最长公共子字符串的所有子字符串 我知道计算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

但是我很难理解它

3 个答案:

答案 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个点存在多个可能值时,可能存在不同的值,即它们在同一点上相同且最高。然后你必须考虑它们中的每一个。