【问题标题】:Dynamic Programming algorithm for Longest Common Subsequence in JavaJava中最长公共子序列的动态规划算法
【发布时间】:2016-08-12 00:07:14
【问题描述】:

我正在尝试为最长公共子序列编写动态编程算法。 返回应该是这个子序列的长度。 但我的算法总是返回 0。我找不到错误。

public static int LCS(String A, String B, int m, int n) {
    int table[][] = new int[m + 1][n + 1];

    for (int i = 0; i < m; i++) {
        table[i][0] = 0;
    }
    for (int i = 1; i < n; i++) {
        table[0][n] = 0;
    }
    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
            if (A.charAt(i) == B.charAt(j)) {
                table[i][j] = table[i - 1][j - 1] + 1;
            } else {
                table[i][j] = max(table[i][j - 1], table[i - 1][j]);
            }
        }
    }

    return table[m][n];
}

private static int max(int a, int b) {
    return (a > b) ? a : b;
}

public static void main(String args[]) {
    Scanner in = new Scanner(System.in);

    System.out.println("Your input words:\n");
    String x = in.nextLine();
    String y = in.nextLine();

    in.close();

    int m = x.length();
    int n = y.length();

    System.out.println("Length of LCS is " + LCS(x, y, m, n));
}

【问题讨论】:

  • 你测试了哪些值?
  • 你的table在方法返回之前是什么样子的?

标签: java algorithm multidimensional-array dynamic-programming


【解决方案1】:

for 循环中的条件使用i &lt; mj &lt; n

因此i 永远不会等于m 并且j 永远不会等于n,所以table[m][n] 永远不会在这些循环中被修改,对吧?

返回的值是table[m][n] 处的值,它永远不会被修改:0

【讨论】:

    【解决方案2】:

    看起来您实现了this algorithm,但有一些错误:

    • 您的循环应该是1..m1..n 包含,这意味着您需要将&lt; 更改为&lt;=

    • charAt() 是从零开始的,所以你需要charAt(i - 1)charAt(j - 1)

    这些不是错误,而是:

    • 在 Java 中初始化为 0 的循环是不必要的。 table 已被 new 运算符初始化为全零。

    • 无需实现max(),因为它已经实现为Math.max()

    所以,这里是使用链接文章中的名称的结果:

    public static int LCS(String X, String Y) {
        final int m = X.length();
        final int n = Y.length();
        int[][] C = new int[m + 1][n + 1];
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                if (X.charAt(i - 1) == Y.charAt(j - 1))
                    C[i][j] = C[i - 1][j - 1] + 1;
                else
                    C[i][j] = Math.max(C[i][j - 1], C[i - 1][j]);
        return C[m][n];
    }
    

    测试

    System.out.println(LCS("This is a test", "Does it work ok?"));
    

    输出

    5
    

    这是最长公共子序列的匹配字母:

    This is a test
       ↑↑↑ ↑ ↑
       ↓↓↓ ↓    ↓
    Does it work ok?
    

    【讨论】:

      猜你喜欢
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      • 2011-02-25
      • 1970-01-01
      • 2012-12-11
      • 2019-05-28
      相关资源
      最近更新 更多