一、问题描述

子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串

cnblogs

belong

比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列。最长公共子序列(Longest Common Subsequence, LCS),顾名思义,是指在所有的子序列中最长的那一个。子串是要求更严格的一种子序列,要求在母串中连续地出现。在上述例子的中,最长公共子序列为blog(cnblogs, belong),最长公共子串为lo(cnblogs, belong)。

二、求解算法

对于母串X=X=, Y=Y=,求LCS与最长公共子串。

暴力解法

假设 m

动态规划

假设Z=Z=是XX与YY的LCS, 我们观察到

如果xm=ynxm=yn,则zk=xm=ynzk=xm=yn,有Zk−1Zk−1是Xm−1Xm−1与Yn−1Yn−1的LCS;

如果xm≠ynxm≠yn,则ZkZk是XmXm与Yn−1Yn−1的LCS,或者是Xm−1Xm−1与YnYn的LCS。

因此,求解LCS的问题则变成递归求解的两个子问题。但是,上述的递归求解的办法中,重复的子问题多,效率低下。改进的办法——用空间换时间,用数组保存中间状态,方便后面的计算。这就是动态规划(DP)的核心思想了。

DP 求解 LCS

用二维数组c[i][j]记录串x1x2⋯xix1x2⋯xi与y1y2⋯yjy1y2⋯yj的LCS长度,则可得到状态转移方程

代码实现

public static int lcs(String str1, String str2) {

int len1 = str1.length();

int len2 = str2.length();

int c[][] = new int[len1+1][len2+1];

for (int i = 0; i <= len1; i++) {

for( int j = 0; j <= len2; j++) {

if(i == 0 || j == 0) {

c[i][j] = 0;

} else if (str1.charAt(i-1) == str2.charAt(j-1)) {

c[i][j] = c[i-1][j-1] + 1;

} else {

c[i][j] = max(c[i - 1][j], c[i][j - 1]);

}

}

}

return c[len1][len2];

}

DP 求解最长公共子串

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

得到转移方程:

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

代码实现

public static int lcs(String str1, String str2) {

int len1 = str1.length();

int len2 = str2.length();

int result = 0; //记录最长公共子串长度

int c[][] = new int[len1+1][len2+1];

for (int i = 0; i <= len1; i++) {

for( int j = 0; j <= len2; j++) {

if(i == 0 || j == 0) {

c[i][j] = 0;

} else if (str1.charAt(i-1) == str2.charAt(j-1)) {

c[i][j] = c[i-1][j-1] + 1;

result = max(c[i][j], result);

} else {

c[i][j] = 0;

}

}

}

return result;

}

总结

以上就是这篇文章的全部内容改了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

最长公共子序列暴力法C语言,利用C++实现最长公共子序列与最长公共子串相关推荐

  1. C语言数组元素总和最大的连续子序列的算法(附完整源码)

    C语言数组元素总和最大的连续子序列的算法 C语言数组元素总和最大的连续子序列的算法完整源码(定义,实现,main函数测试) C语言数组元素总和最大的连续子序列的算法完整源码(定义,实现,main函数测 ...

  2. 20200117:(leetcode)最长回文子串(暴力法)

    最长回文子串 题目 基本思路 代码实现 题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: ...

  3. LeetCode--84.柱状图中最大的矩形(暴力法,单调栈)

    柱状图中最大的矩形(暴力法,单调栈) 1. 题目描述 2. 题目分析 3. C语言实现 3.1 暴力法 3.2 单调栈 4. Java实现 1. 题目描述 难度:困难 2. 题目分析 这道题有两种解法 ...

  4. 几个常见的简单的算法(暴力法,递推法,枚举法,递归法,分治法,贪心法,回溯法)

    最近在学习算法相关知识. 通过买的视频教程了解到了一些简单的算法,为了加深感悟,同时也为了理解,将这几个常见的算法的定义进行记录. 算法是程序的灵魂,也可以认为是程序最重要的部分. 在通过算法解决问题 ...

  5. 如何代理ip25采取云速捷_长租公寓暴雷,作为租客应如何维护自己的合法权益?...

    一 最近长租公寓暴雷的消息频出,比如乐伽.悦如公寓.杭州德寓科技.适享.友客等,对于暴雷的长租公寓,租客们应如何维护自己合法权益. 小A作为一名白领,在某长租公寓租房1年,签署购房合同1年,缴纳1个月 ...

  6. R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format)、指定行标识符变量、并自定义生成的长表的标识符列的名称

    R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format).指定行标识符变量.并自定义生成的长表的标识符列的名称 目录

  7. R语言使用reshape2包的dcast函数将dataframe从长表到宽表(Long- to wide-format)、指定单个标识符、、表格转化的时候值不唯一设置聚合函数(均值)

    R语言使用reshape2包的dcast函数将dataframe从长表到宽表(Long- to wide-format).指定单个标识符..表格转化的时候值不唯一设置聚合函数(均值) 目录

  8. R语言将dataframe数据从宽表(wide)变为长表(long)实战:tidyr包的gather函数、cdata包的unpivot_to_blocks函数、data.table使用melt函数

    R语言将dataframe数据从宽表(wide)变为长表(long)实战:tidyr包的gather函数.cdata包的unpivot_to_blocks函数.data.table使用melt函数 目 ...

  9. 51Nod-1080 两个数的平方和【暴力法】

    1080 两个数的平方和 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数N,将N表示为2个整数i j的平方和(i <= j),如果有多种表示,按照 ...

最新文章

  1. python3环境下“No module named nibabel”的解决办法
  2. G6 图可视化引擎——核心概念——节点/边/Combo——内置节点——Rect
  3. VMware虚拟机NAT模式网络配置图文教程
  4. Flink 实时计算 - 维表 Join 解读
  5. 云数据库RDS基础版的优势及适用场景
  6. python性能测试模块_技巧python模块性能测试-阿里云开发者社区
  7. 前端事件绑定知识点(面试常考)
  8. zabbix服务器搭建
  9. 在java中excel格式变为zip什么原因_Excel工作表中最常见的8类问题,你一定遇到过,附解决方法!...
  10. UserWarning: h5py is running against HDF5 1.10.5 when it was built against 1.10.4
  11. ASP.NET中防止页面多次提交的代码实现
  12. tomcat如何设置账号和密码
  13. java 面单模板_顺丰电子面单JSON请求格式
  14. 中望cad文字显示问号怎么办_如果CAD工程图显示乱码怎么办?
  15. 思科3650交换机的密码恢复
  16. 燃烧的远征java(三)-Struts+Spring+Hibernate:java的几种对象(PO,VO,DAO,BO,POJO)解释
  17. PMP知识点:工作绩效数据、信息和报告的区别
  18. BIOS中VT虚拟技术已经开启,但任务管理器中仍显示虚拟化已禁用
  19. python按照号段生成手机号接收验证码_django 发送手机验证码的示例代码
  20. Centos用speedtest.py测试服务器(国外)上传下载速度

热门文章

  1. 『 DSSM』A Multi-View Deep Learning Approach for Cross Domain User Modeling in Recommendation Systems
  2. 《都挺好》苏明哲清华高材生,苏明玉草根创业,程序员引发的思考
  3. Go语言的正则表达式简介
  4. 简单认识CPT、思科设备配置(一)
  5. Flutter-Wrap的使用说明
  6. 第二十五届中国烘焙展览会10万平米,全面升级,大不一样
  7. Java泛型与Kotlin泛型
  8. vue.js项目中配置mapbox可视化地图api
  9. Deferred 对象
  10. vanilla_如何使用Vanilla JavaScript构建钢琴键盘