先来说明下什么是最长公共子序列,什么是是最长公共子串,举一个实际例子,myblogs与belong,最长公共子序列为blog(myblogs, belong),最长公共子串为lo(myblogs, belong)也就是说子串要求在原字符串中是连续的,而最长公共子序列则并不要求连续。

最长公共子序列问题

问题描述

给两个字条串X="ABCBDAB",Y="BDCABA",求这两个字符串的最长公共子序列。

问题分析

这里只求这个公共子序列的长度。 利用动态规划的思想分析。 定义一个前缀概念:

给定一个序列X = <x1,x2 ,..., xm>,对于i = 0,1,...,m,定义X的第i前缀为Xi = <x1,x2 ,..., xi>。例如,若 X = <A,B,C,B,D,A,B>,则 X4 = <A,B,C,B>,X0为空串。

则减小问题的规模,X、Y都去掉一个字符时,他们的最长公共子串和X与Y的最长公共子串有什么关系呢?

X = <x0,x1,x2 ,...>Y = <y0,y1,y2 ,...> 为两个序列,Z =<z0,z1,z2 ,...为X和Y的任意LCS。c[i,j]表示Xi和Yj的LCS的长度,则: - 如果Xi = Yj,则 c[i,j]=c[i-1,j-1]+1。 - 如果 Xi ≠ Yj,则 c[i,j]=max(c[i-1,j],c[i,j-1])

此时要求i>0,j>0,即X、Y的字符个数都至少为两个,因为上面的递推公式都用到了c[i-1,j-1]

考虑初始条件,如果X,Y有一个为空串,则就没有公共子序列了。

如果X,Y有一个为只含一个字符的子符串,则公共子串要么是没有,可以看成是长度为0,要么是就是这个字符了其长度为1.

按这个思路,先计算初始条件,然后利用递推公式计算所有值,代码实现如下。

代码实现

int lcs(string word1, string word2) {int size1 = word1.size();int size2 = word2.size();int max_length=0;int dp[size1][size2];//初值比较,字符串的第一个字符if(word1[0] == word2[0]){dp[0][0] =1;max_length = 1;}else{dp[0][0] =0;}//字符串word2的一个字符,各word1的所有字符for(int i = 1,j=0; i<size1; i++){if(word1[i] == word2[j]){dp[i][j] = 1;max_length = 1;}else{dp[i][j] = dp[i-1][j];}}//字符串word1的一个字符,各word2的所有字符for(int j=1,i=0; j<size2; j++){if(word1[i] == word2[j]){dp[i][j] = 1;max_length = 1;}else{dp[i][j] = dp[i][j-1];}}//利用上面的初始化值来迭代for(int i =1; i<size1; i++){for(int j=1; j<size2;j++){dp[i][j] =0;if(word1[i] == word2[j]){dp[i][j] = dp[i-1][j-1] +1;}else{dp[i][j] = max(dp[i-1][j],dp[i][j-1]);}if(dp[i][j] > max_length ){max_length = dp[i][j] ;}}}return max_length;
}

最长公共子串问题

这里以leetcode上的一个最长公共子数组问题来说明。

问题描述

给数组A,B,求A,B的最长公共子数组,如 Input: A: [1,2,3,2,1] B: [3,2,1,4,7] Output: 3 解释,最长公共子数组为 [3, 2, 1]。

问题分析

和最长公共子序列问题类似,不过c[i][j]定义应该是稍有不同的,这里的c[i][j],表示A[0...i]和B[0...j]的最长公共子串,且此公共子串中一定包含A[i],B[j]的,最长公共子序列中的定义可以不包括A[i],B[j]的。

此时的递推公式也稍有不同了:

  • 如果A[i] = B[j],则 c[i,j]=c[i-1,j-1]+1
  • 如果 A[i] ≠ B[j],则 c[i,j]=0

代码实现

int findLength(vector<int>& A, vector<int>& B) {int asize=A.size();int bsize=B.size();int dp[asize][bsize];int max = 0;for(int i=0,j=0; i<asize; i++){if(A[i] == B[j]){dp[i][j] = 1;max = 1;}else{dp[i][j] = 0;}}for(int i=0,j=0; j<bsize; j++){if(A[i] == B[j]){dp[i][j] = 1;max = 1;}else{dp[i][j] = 0;}}for(int i=1; i<asize; i++){for(int j = 1; j<bsize; j++){if(A[i] == B[j]){dp[i][j] = dp[i-1][j-1] + 1;}else{dp[i][j] = 0;}if(dp[i][j] > max){max = dp[i][j];}}}return max;
}

todo: - 补充c数组的表格 - 加求具体序列的方法

两个字符串的最长公共子序列长度_【面试】动态规划-之最长公共子序列、最长公共子串问题...相关推荐

  1. 两个字符串的最长公共子序列长度_程序员编程算法,解决文本相似度问题的最长公共子序列算法!...

    在前面我讲解了如何通过最长公共子串来求解两个文本的相似度问题,但它有一定缺陷,举个例子,看下面的两个字符串 我爱吃小青菜和各种鲜水果. 我很爱吃青菜与各样水果. 上面两个字符串,如果通过计算子串来求相 ...

  2. 两个字符串的最长公共子序列长度_算法学习笔记(58): 最长公共子序列

    (为什么都更了这么多篇笔记了,这时候才讲这么基础的内容呢?因为我本来以为LCS这种简单的DP不用讲的,结果CF不久前考了LCS的变式,然后我发现由于自己对LCS一点都不熟,居然写不出来 ,于是决定还是 ...

  3. 两个字符串的最长公共子序列长度_求2个字符串的最长公共子序列和最长公共子字符串...

    一. 最长公共子序列 定义: 一个数列S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列. 例如:输入两个字符串BDCABA和 ABCBDA ...

  4. 两个字符串的最长公共子序列长度_输出两个字符串的最长公共子串和最长公共子序列...

    输出两个字符串的最长公共子串和最长公共子序列.求解两个字符串的最长公共子串和最长公共子序列在方法上很接近,都是动态规划.只不过在递推方程上有一些不一样. 求两个字符串的最长公共子串 #include ...

  5. 最长回文串_第78天——第78题(最长回文串 )

    今天又是阴天,不过阴天凉快,我喜欢. 第78天--第78题(最长回文串) 看题目! 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串. 在构造过程中,请注意区分大小写.比如 ...

  6. c 最大子序列和_算法总结:左神class8—跳台阶+最长递增公共子序列

    [跳台阶]有n级台阶,一个人每次上一级或者两级,问有多少种走完n级台阶的方法? public int s1(int n){ if (n< 1){ return 0; if(n == 1 || n ...

  7. python 最长公共子序列长度_python实现最长公共子序列

    最长公共子序列python实现,最长公共子序列是动态规划基本题目,下面按照动态规划基本步骤解出来. 1.找出最优解的性质,并刻划其结构特征 序列a共有m个元素,序列b共有n个元素,如果a[m-1]== ...

  8. LeetCode 1616. 分割两个字符串得到回文串

    文章目录 1. 题目 2. 解题 1. 题目 给你两个字符串 a 和 b ,它们长度相同. 请你选择一个下标,将两个字符串都在 相同的下标 分割开. 由 a 可以得到两个字符串: aprefix 和 ...

  9. 给定两个字符串,确定其中一个字符串的字符重新排列后,能否变成另一个字符串...

    1 /* 2 * 给定两个字符串,确定其中一个字符串的字符重新排列后,能否变成另一个字符串,其实也就是变位词问题 3 * 比如说 a='abc' b='acb'是可以通过a变成b的 4 * 思路; 5 ...

最新文章

  1. 使用 Gitlab 进行嵌入式软件开发技巧
  2. IBM X3650 M2 BR10i卡的阵列配置方法
  3. 驱动中获取PsActiveProcessHead变量地址的五种方法
  4. 【干货】精通网红OSPF协议---进阶篇
  5. 使用camera_calibration对xtion pro live深度相机进行参数标定,rosdep install camera_calibration报错Rosdep cannot find
  6. 老板让我十分钟上手nx-admin
  7. Vue本地图片循环加载显示不出来,vue img标签 :src地址拼接
  8. mysql 主从同步不一致_为什么mysql会经常出现主从同步不一致的情况
  9. ZOJ 3867 Earthstone: Easy Version
  10. 网页设计中最常用的字体
  11. Flex和Flash之间相互调用
  12. pip:你真的熟悉怎么用了吗?
  13. javascript一维数组的排序
  14. Hi3559V100基本信息
  15. 干货 | 推荐几款实用的思维导图工具
  16. Python百行代码随机生成姓名
  17. B02 - 025、使用Hive配置mysql作为元数据库
  18. Cubieboard安装系统
  19. LOJ#2863. 「IOI2018」组合动作 交互
  20. c++ sprintf

热门文章

  1. 卫星参数大全_【视频】早期国外做工精良的海事卫星电话机拆解
  2. delete不调用析构函数的两种情况
  3. Android开发之关于MVVM架构中视图数据绑定框架dataBinding的基本用法
  4. Spring中注解大全和应用
  5. jquery data()
  6. javascript实现汉诺塔动画效果
  7. 深入Java核心 Java内存分配原理精讲(3)
  8. [Android学习笔记]使用ListView
  9. Console-算法[for,if]-一堆桃子和一只猴子
  10. 实现pxe的自动化安装