最长公共子序列暴力法C语言,利用C++实现最长公共子序列与最长公共子串
一、问题描述
子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串
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++实现最长公共子序列与最长公共子串相关推荐
- C语言数组元素总和最大的连续子序列的算法(附完整源码)
C语言数组元素总和最大的连续子序列的算法 C语言数组元素总和最大的连续子序列的算法完整源码(定义,实现,main函数测试) C语言数组元素总和最大的连续子序列的算法完整源码(定义,实现,main函数测 ...
- 20200117:(leetcode)最长回文子串(暴力法)
最长回文子串 题目 基本思路 代码实现 题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: ...
- LeetCode--84.柱状图中最大的矩形(暴力法,单调栈)
柱状图中最大的矩形(暴力法,单调栈) 1. 题目描述 2. 题目分析 3. C语言实现 3.1 暴力法 3.2 单调栈 4. Java实现 1. 题目描述 难度:困难 2. 题目分析 这道题有两种解法 ...
- 几个常见的简单的算法(暴力法,递推法,枚举法,递归法,分治法,贪心法,回溯法)
最近在学习算法相关知识. 通过买的视频教程了解到了一些简单的算法,为了加深感悟,同时也为了理解,将这几个常见的算法的定义进行记录. 算法是程序的灵魂,也可以认为是程序最重要的部分. 在通过算法解决问题 ...
- 如何代理ip25采取云速捷_长租公寓暴雷,作为租客应如何维护自己的合法权益?...
一 最近长租公寓暴雷的消息频出,比如乐伽.悦如公寓.杭州德寓科技.适享.友客等,对于暴雷的长租公寓,租客们应如何维护自己合法权益. 小A作为一名白领,在某长租公寓租房1年,签署购房合同1年,缴纳1个月 ...
- R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format)、指定行标识符变量、并自定义生成的长表的标识符列的名称
R语言使用reshape2包的melt函数将dataframe从宽表到长表(Wide- to long-format).指定行标识符变量.并自定义生成的长表的标识符列的名称 目录
- R语言使用reshape2包的dcast函数将dataframe从长表到宽表(Long- to wide-format)、指定单个标识符、、表格转化的时候值不唯一设置聚合函数(均值)
R语言使用reshape2包的dcast函数将dataframe从长表到宽表(Long- to wide-format).指定单个标识符..表格转化的时候值不唯一设置聚合函数(均值) 目录
- 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函数 目 ...
- 51Nod-1080 两个数的平方和【暴力法】
1080 两个数的平方和 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数N,将N表示为2个整数i j的平方和(i <= j),如果有多种表示,按照 ...
最新文章
- python3环境下“No module named nibabel”的解决办法
- G6 图可视化引擎——核心概念——节点/边/Combo——内置节点——Rect
- VMware虚拟机NAT模式网络配置图文教程
- Flink 实时计算 - 维表 Join 解读
- 云数据库RDS基础版的优势及适用场景
- python性能测试模块_技巧python模块性能测试-阿里云开发者社区
- 前端事件绑定知识点(面试常考)
- zabbix服务器搭建
- 在java中excel格式变为zip什么原因_Excel工作表中最常见的8类问题,你一定遇到过,附解决方法!...
- UserWarning: h5py is running against HDF5 1.10.5 when it was built against 1.10.4
- ASP.NET中防止页面多次提交的代码实现
- tomcat如何设置账号和密码
- java 面单模板_顺丰电子面单JSON请求格式
- 中望cad文字显示问号怎么办_如果CAD工程图显示乱码怎么办?
- 思科3650交换机的密码恢复
- 燃烧的远征java(三)-Struts+Spring+Hibernate:java的几种对象(PO,VO,DAO,BO,POJO)解释
- PMP知识点:工作绩效数据、信息和报告的区别
- BIOS中VT虚拟技术已经开启,但任务管理器中仍显示虚拟化已禁用
- python按照号段生成手机号接收验证码_django 发送手机验证码的示例代码
- Centos用speedtest.py测试服务器(国外)上传下载速度
热门文章
- 『 DSSM』A Multi-View Deep Learning Approach for Cross Domain User Modeling in Recommendation Systems
- 《都挺好》苏明哲清华高材生,苏明玉草根创业,程序员引发的思考
- Go语言的正则表达式简介
- 简单认识CPT、思科设备配置(一)
- Flutter-Wrap的使用说明
- 第二十五届中国烘焙展览会10万平米,全面升级,大不一样
- Java泛型与Kotlin泛型
- vue.js项目中配置mapbox可视化地图api
- Deferred 对象
- vanilla_如何使用Vanilla JavaScript构建钢琴键盘