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

9人阅读 评论(0) 收藏 举报
分类:

最长公共子序列

1).子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串
cnblogs
belong
比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列。最长公共子序列(Longest Common Subsequence,LCS),顾名思义,是指在所有的子序列中最长的那一个。子串是要求更严格的一种子序列,要求在母串中连续地出现。在上述例子的中,最长公共子序列为blog(cnblogs,belong),最长公共子串为lo(cnblogs, belong)。
2). 求解算法对于母串X=, Y=,求LCS与最长公共子串。
暴力解法
假设 m
动态规划
假设Z=是X与Y的LCS, 我们观察到
如果Xm=Yn,则Zk=Xm=Yn,有Zk−1是Xm−1与Yn−1的LCS;
如果Xm≠Yn,则Zk是Xm与Yn−1的LCS,或者是Xm−1与Yn的LCS。
因此,求解LCS的问题则变成递归求解的两个子问题。但是,上述的递归求解的办法中,重复的子问题多,效率低下。改进的办法——用空间换时间,用数组保存中间状态,方便后面的计算。这就是动态规划(DP)的核心思想了。
DP求解LCS
用二维数组c[i][j]记录串x1x2⋯xi与y1y2⋯yj的LCS长度,则可得到状态转移方程
这里写图片描述

代码实现

 int findLCS(string A, int n, string B, int m) {
        if(A.empty() || B.empty() || n == 0 || m == 0)
            return 0;
        vector<vector<int>> num(n+1, vector<int>(m+1));
        for(int i = 0; i <= n; i++){
            for(int j = 0; j <= m; j++){
                if(i == 0 || j == 0)
                    num[i][j] = 0;
                else if(A[i-1] == B[j-1])
                    num[i][j] = num[i-1][j-1] + 1;
                else
                    num[i][j] = max(num[i-1][j], num[i][j-1]);
            }
        }
        return num[n][m];
    }

最长公共子串

前面提到了子串是一种特殊的子序列,因此同样可以用DP来解决。定义数组的存储含义对于后面推导转移方程显得尤为重要,糟糕的数组定义会导致异常繁杂的转移方程。考虑到子串的连续性,将二维数组c[i][j]用来记录具有这样特点的子串——结尾同时也为为串x1x2⋯xi与y1y2⋯yj的结尾——的长度。
得到转移方程:
这里写图片描述

最长公共子串的长度为 max(c[i,j]), i∈{1,⋯,m},j∈{1,⋯,n}。
代码实现

    int findLongest(string A, int n, string B, int m) {
        if(A.empty() || B.empty() || n == 0 || m == 0)
            return 0;
        vector<vector<int>> num(n+1, vector<int>(m+1));
        int result = 0;
        for (int i = 0; i <= n; i++){
            for(int j = 0; j <= m; j++){
                if (i == 0 || j == 0)
                        num[i][j] = 0;
               else if(A[i-1] == B[j-1]){
                    num[i][j] = num[i - 1][j - 1] + 1;
                    result = max(result, num[i][j]);
               }else
                   num[i][j] = 0;
            }
        }
           return result;
        // write code here
    }
查看评论

电子商务实战课程

-
  • 1970年01月01日 08:00

最长公共子序列与最长公共子串(DP)

1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogsbelong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序...
  • u012102306
  • u012102306
  • 2016-11-16 11:14:08
  • 9860

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

最长公共子序列问题以及背包问题都是DP(动态规划)算法的经典题目,值得深度挖掘以致了解DP算法思想。问题如下: 最长公共子序列 时间限制:3000 ms  |  内存限制:6553...
  • u014492609
  • u014492609
  • 2014-08-08 15:48:00
  • 1380

LCS(最长公共子序列)和dp(动态规划)

参照:v_JULY_v        最长公共子序列定义:         注意最长公共子串(Longest CommonSubstring)和最长公共子序列(LongestCommon Subs...
  • u011479875
  • u011479875
  • 2015-04-30 12:15:49
  • 1114

最长公共子序列(LCS问题)的DP解法

呃。。大一做过,毕竟是ACM入门DP题,但是大三的我已然忘了具体咋做了,只记得是DP,面试常会问这个问题,所以有必要搞明白。 题目描述略。 解题思想就是DP,DP无外乎需要知道两个东西,一是状态是什么...
  • u013303743
  • u013303743
  • 2016-04-23 10:40:52
  • 1122

dp--poj1458最长公共子序列

很水的一题 但是我居然细节出错了尼玛。。 #include #include #include using namespace std; int max3(int a,int b,...
  • u011644423
  • u011644423
  • 2014-08-12 10:37:42
  • 450

DP---最长公共子序列&最长公共字串

【动态规划】最长公共子序列与最长公共子串 1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong ...
  • cp7319472
  • cp7319472
  • 2017-05-01 20:45:08
  • 119

最长公共子序列,子串(打印一个、打印多个)

最长公共子序列(输出最大长度与多个不重复子序列) #include #include #include #include using namespace std; string printOne(s...
  • luckyrass
  • luckyrass
  • 2016-06-13 13:10:50
  • 908

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

题目:poj 1458   Common Subsequence Description A subsequence of a given sequence is the given sequen...
  • fangjian1204
  • fangjian1204
  • 2014-08-19 18:31:35
  • 1749

最长公共子序列(nlogn)

最长公共子序列(LCS)最常见的算法是时间复杂度为O(n^2)的动态规划(DP)算法,但在James W. Hunt和Thomas G. Szymansky 的论文"A Fast Algorithm ...
  • wdq347
  • wdq347
  • 2013-05-31 16:03:56
  • 7644
    个人资料
    持之以恒
    等级:
    访问量: 1351
    积分: 409
    排名: 12万+
    文章存档
    最新评论