1、先科普下最长公共子序列 & 最长公共子串的区别:

找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。

(1)递归方法求最长公共子序列的长度

    1)设有字符串a[0...n],b[0...m],下面就是递推公式。

当数组a和b对应位置字符相同时,则直接求解下一个位置;当不同时取两种情况中的较大数值。

    

    2)代码如下:

  1. #include<stdio.h>
  2. #include<string.h>
  3. char a[30],b[30];
  4. int lena,lenb;
  5. int LCS(int,int);  ///两个参数分别表示数组a的下标和数组b的下标
  6.  
  7. int main()
  8. {
  9. strcpy(a,"ABCBDAB");
  10. strcpy(b,"BDCABA");
  11. lena=strlen(a);
  12. lenb=strlen(b);
  13. printf("%d\n",LCS(0,0));
  14. return 0;
  15. }
  16.  
  17. int LCS(int i,int j)
  18. {
  19. if(i>=lena || j>=lenb)
  20. return 0;
  21. if(a[i]==b[j])
  22. return 1+LCS(i+1,j+1);
  23. else
  24. return LCS(i+1,j)>LCS(i,j+1)? LCS(i+1,j):LCS(i,j+1);
  25. }

用递归的方法优点是编程简单,容易理解。缺点是效率不高,有大量的重复执行递归调用,而且只能求出最大公共子序列的长度,求不出具体的最大公共子序列。

  (2)动态规划求最长公共子序列的长度

    动态规划采用二维数组来标识中间计算结果,避免重复的计算来提高效率。

    1)最长公共子序列的长度的动态规划方程

    设有字符串a[0...n],b[0...m],下面就是递推公式。字符串a对应的是二维数组num的行,字符串b对应的是二维数组num的列。

    

代码如下:

  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. char a[500],b[500];
  5. char num[501][501]; ///记录中间结果的数组
  6. char flag[501][501]; ///标记数组,用于标识下标的走向,构造出公共子序列
  7. void LCS(); ///动态规划求解
  8. void getLCS(); ///采用倒推方式求最长公共子序列
  9.  
  10. int main()
  11. {
  12. int i;
  13. strcpy(a,"ABCBDAB");
  14. strcpy(b,"BDCABA");
  15. memset(num,0,sizeof(num));
  16. memset(flag,0,sizeof(flag));
  17. LCS();
  18. printf("%d\n",num[strlen(a)][strlen(b)]);
  19. getLCS();
  20. return 0;
  21. }
  22.  
  23. void LCS()
  24. {
  25. int i,j;
  26. for(i=1;i<=strlen(a);i++)
  27. {
  28. for(j=1;j<=strlen(b);j++)
  29. {
  30. if(a[i-1]==b[j-1]) ///注意这里的下标是i-1与j-1
  31. {
  32. num[i][j]=num[i-1][j-1]+1;
  33. flag[i][j]=1; ///斜向下标记
  34. }
  35. else if(num[i][j-1]>num[i-1][j])
  36. {
  37. num[i][j]=num[i][j-1];
  38. flag[i][j]=2; ///向右标记
  39. }
  40. else
  41. {
  42. num[i][j]=num[i-1][j];
  43. flag[i][j]=3; ///向下标记
  44. }
  45. }
  46. }
  47. }
  48.  
  49. void getLCS()
  50. {
  51.  
  52. char res[500];
  53. int i=strlen(a);
  54. int j=strlen(b);
  55. int k=0; ///用于保存结果的数组标志位
  56. while(i>0 && j>0)
  57. {
  58. if(flag[i][j]==1) ///如果是斜向下标记
  59. {
  60. res[k]=a[i-1];
  61. k++;
  62. i--;
  63. j--;
  64. }
  65. else if(flag[i][j]==2) ///如果是斜向右标记
  66. j--;
  67. else if(flag[i][j]==3) ///如果是斜向下标记
  68. i--;
  69. }
  70.  
  71. for(i=k-1;i>=0;i--)
  72. printf("%c",res[i]);
  73. }

(3)图示

最长公共子串

  1. import java.util.Scanner;
  2.  
  3. public class Main {
  4. public static void main(String[] args) {
  5. Scanner sc = new Scanner(System.in);
  6. Main mainObj = new Main();
  7. int len = mainObj.getCommonStrLength(sc.next(),sc.next());
  8. System.out.println(len);
  9. }
  10.  
  11. int getCommonStrLength(String str1, String str2) {
  12. str1 = str1.toLowerCase();
  13. str2 = str2.toLowerCase();
  14. int len1 = str1.length();
  15. int len2 = str2.length();
  16. String min = null;
  17. String max = null;
  18. String target = null;
  19. min = len1 <= len2 ? str1 : str2;
  20. max = len1 > len2 ? str1 : str2;
  21. //最外层:min子串的长度,从最大长度开始
  22. for (int i = min.length(); i >= 1; i--) {
  23. //遍历长度为i的min子串,从0开始
  24. for (int j = 0; j <= min.length() - i; j++) {
  25. target = min.substring(j, j + i);
  26. //遍历长度为i的max子串,判断是否与target子串相同,从0开始
  27. for (int k = 0; k <= max.length() - i; k++) {
  28. if (max.substring(k,k + i).equals(target)) {
  29. return i;
  30. }
  31. }
  32. }
  33. }
  34. return 0;
  35. }
  36. }

最长公共子序列PK最长公共子串的更多相关文章

  1. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

  2. 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串

    LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...

  3. 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446

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

  4. 用Python计算最长公共子序列和最长公共子串

    如何用Python计算最长公共子序列和最长公共子串 1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公 ...

  5. 动态规划1——最长递增子序列、最长公共子序列、最长公共子串(python实现)

    目录 1. 最长递增序列 2. 最长公共子序列 3. 最长公共子串 1. 最长递增序列 给定一个序列,找出其中最长的,严格递增的子序列的长度(不要求连续). 解法一:动态规划 通过一个辅助数组记录每一 ...

  6. [Python]最长公共子序列 VS 最长公共子串[动态规划]

    前言 由于原微软开源的基于古老的perl语言的Rouge依赖环境实在难以搭建,遂跟着Rouge论文的描述自行实现. Rouge存在N.L.S.W.SU等几大子评估指标.在复现Rouge-L的函数时,便 ...

  7. O(n log n)求最长上升子序列与最长不下降子序列

    考虑dp(i)表示新上升子序列第i位数值的最小值.由于dp数组是单调的,所以对于每一个数,我们可以二分出它在dp数组中的位置,然后更新就可以了,最终的答案就是dp数组中第一个出现正无穷的位置. 代码非 ...

  8. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

  9. 【ZH奶酪】如何用Python计算最长公共子序列和最长公共子串

    1. 什么是最长公共子序列?什么是最长公共子串? 1.1. 最长公共子序列(Longest-Common-Subsequences,LCS) 最长公共子序列(Longest-Common-Subseq ...

随机推荐

  1. Zookeeper 分布式环境搭建

    一.前期环境 安装概览 IP Host Name     Software     192.168.23.128     ae01 JDK 1.7 192.168.23.129 ae02 JDK 1. ...

  2. WPF画线问题,几千条以后就有明显的延迟了。

      我现在是这么画的,class A { private GeometryGroup _lines; private Path _path; public A() {    _path.Data = ...

  3. NUC_HomeWork1 -- POJ2067(最短路)

    C - Fire Station Description A city is served by a number of fire stations. Some residents have comp ...

  4. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  5. ajaxFileUpload + lua-resty-upload 上传文件

    ajaxFileUpload下载地址 地址:http://pan.baidu.com/s/1mgJypz6 html页面 <!DOCTYPE HTML PUBLIC "-//W3C// ...

  6. [Leetcode] Word BreakII

    Question: Given a string s and a dictionary of words dict, add spaces in s to construct a sentence w ...

  7. 手机web站点和手机app 技术选型的困惑于思考

    今年一直在关注移动端技术的发展,自己也用博客园的rss接口玩了半年,关于技术选型的困惑和大家说说 一 趋势 随着手机硬件不断的升级,外加4g牌照的发放,不出2年时间移动端web站点和手机app一定会进 ...

  8. JavaScript基础学习篇

    1.alert消息弹出框 alert(字符串或变量); 消息对话框通常可以用于调试程序. 与document.write 相似. 2.确认:confirm消息对话框 confirm(弹出时要显示的文本 ...

  9. row_number() over order by与利用rownum查询分页效率分析

    实际测试: 数据库:70万条数据 查询第10000页,每页10条.row_number() 耗时: 2.2秒rownum 耗时:1.3秒 查询第20000页,每页10条.row_number() 耗时 ...

  10. 使用ADO.NET访问数据库

    第一种连接数据库的方法:可以使用.ET Framework提供程序的sqlConnection对象,使用无参数的构造函数创建Connection对象,代码如下: string strcon = &qu ...