最长公共子串和最长公共子序列(LCS问题)

Posted yangfei629

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长公共子串和最长公共子序列(LCS问题)相关的知识,希望对你有一定的参考价值。

一、区别


给定两个字符串,求LCS

 

最长公共子串 (Longest Common Substring): 要求是连续的字符串

最长公共子序列(Longest Common Subsequence):要求子字符串相对顺序不变即可

 

二、动态规划求解


 

1、最长公共子串

      给定两个字符串A 和 B

      用二维数组 d[i][j] 表示 A的前i个字符串-B的前j个字符串 的最长公共子串长度

     d[i][j] = d[i-1][j-1] + 1 (A[i] == B[j])

                 0                     (A[i] != B[j])  (注意此处为了求解子串 返回0,而不是Max(d[i-1][j], d[i][j-1]))

    例 如下, 取最大值=2

      技术图片

 

    

      此时列出最长公共子串,如下找出最大的值2,向左上角递进,直到值=1

     则找出最长公共子串 AB BD AB

技术图片

 

 

2、最长公共子序列

 

     d[i][j] = d[i-1][j-1] + 1 (A[i] == B[j])

                 Max(d[i-1][j], d[i][j-1])

    

     最长公共子序列必然==右下角的值==4

技术图片

 

 

   列出所有的最长公共子序列:

        从右下角开始计算

 

  1. 如果d[i][j]对应的A[i-1] == B[j-1],则把这个字符放入 LCS 中,并跳入d[i-1][j-1]中继续进行判断;
  2. 如果格子d[i][j]对应的 A[i-1] ≠ B[j-1],则比较d[i-1][j]和d[i][j-1]的值,跳入值较大的格子继续进行判断;(此时两边相等=说明有多个结果)
  3. 直到 i 或 j 小于等于零为止,倒序输出 LCS

 技术图片

 

 输出:“BDAB”、“BCAB”、“BCBA”。

 递归代码:

public List<String> getLcsString(int i,int j, int[][] d) {
        List<String> lcsList = new ArrayList<>();

        if (A.indexOf(i) == B.indexOf(j)) {
            List<String> subLcsList = getLcsString(i-1,j-1,d);
            lcsList.addAll(subLcsList.stream().map(str -> str+A.indexOf(i)).collect(Collectors.toList()));
        } else if (d[i-1][j] == d[i][j-1]){
            List<String> subLcsList1 = getLcsString(i-1,j,d);
            List<String> subLcsList2 = getLcsString(i,j-1,d);
            lcsList.addAll(subLcsList1);
            lcsList.addAll(subLcsList2);
        } else if (d[i-1][j] > d[i][j-1]){
            List<String> subLcsList = getLcsString(i-1,j,d);
            lcsList.addAll(subLcsList);
        } else {
            List<String> subLcsList = getLcsString(i,j-1,d);
            lcsList.addAll(subLcsList);
        }
        return lcsList;
    }

  

 参考:https://zhuanlan.zhihu.com/p/68409952

以上是关于最长公共子串和最长公共子序列(LCS问题)的主要内容,如果未能解决你的问题,请参考以下文章

最长公共子串和最长公共子序列

每日一题-——最长公共子序列(LCS)与最长公共子串

最长公共子序列和最长公共子串

动态规划:最长公共子串和最长公共子序列

最长公共子序列(LCS)问题

最长公共子序列(LCS)