欢迎访问宙启技术站
智能推送

编写Java中的最长公共子序列函数

发布时间:2023-06-02 06:19:54

最长公共子序列(Longest Common Subsequence,简称LCS)是指给定两个序列X和Y,找出两个序列中共同的部分,并且该部分是所有共同部分中最长的一个。LCS函数可以用于字符串匹配、DNA分析、文本比对等领域。

在Java语言中,最长公共子序列函数可以通过动态规划的思路来实现。动态规划的思路是建立一个二维数组dp,dp[i][j]表示X的前i个字符和Y的前j个字符的最长公共子序列的长度。具体代码如下:

public static String LCS(String str1, String str2) {
    int m = str1.length(), n = str2.length();
    int[][] dp = new int[m + 1][n + 1];

    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    StringBuilder result = new StringBuilder();
    int i = m, j = n;
    while (i > 0 && j > 0) {
        if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
            result.append(str1.charAt(i - 1));
            i--;
            j--;
        } else if (dp[i - 1][j] >= dp[i][j - 1]) {
            i--;
        } else {
            j--;
        }
    }

    return result.reverse().toString();
}

上述代码中,函数LCS接收两个参数str1和str2,分别表示两个字符串。首先,我们得到字符串str1和str2的长度m和n,并且建立一个(m+1)×(n+1)的二维数组dp。接着,我们使用两层循环来遍历整个dp数组,计算每个dp[i][j]的值。

当str1的第i个字符和str2的第j个字符相等时,说明它们在最长公共子序列中,此时dp[i][j]的值等于dp[i-1][j-1]+1,即str1的前一个字符和str2的前一个字符的最长公共子序列长度加1。

当str1的第i个字符和str2的第j个字符不相等时,说明它们不在最长公共子序列中。此时,我们需要比较dp[i-1][j]和dp[i][j-1]中的最大值作为dp[i][j]的值。其中,dp[i-1][j]表示str1的前一个字符和str2的当前字符的最长公共子序列长度,dp[i][j-1]表示str1的当前字符和str2的前一个字符的最长公共子序列长度。

最后,我们使用一个while循环来回溯dp数组,得到最长公共子序列的内容,并且返回它们的字符串形式。回溯过程中,当str1的第i个字符和str2的第j个字符相等时,说明它们在最长公共子序列中,将它们添加到结果中,并且i和j分别减1。当dp[i-1][j]大于或等于dp[i][j-1]时,说明结果中要包含str1的第i-1个字符,i减1;否则结果中要包含str2的第j-1个字符,j减1。

综上所述,以上是Java中最长公共子序列函数的详细实现及解释。