最大公共子序列 vs 最大公共子串

动态规划 最长公共子序列 过程图解 1.基本概念       首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。什么是子串呢?给定串中任意个连续的字符组成的子序列称为该串的子串。给一个图再解释一下:        如 阅读详情

        最大公共子序列及最大公共子串问题是动态规划算法中比较经典,而且经常在一起提到。其主要的不同点就是公共子序列不要求元素的下标值连续,而公共字串则要求下标连续。

     动态规划算法重点是要发现题目的最优解的结构特征,尽可能用一个递归的方程式进行描述从而实现自底向上计算最优值。一般这里的最优值还不是动态规划题目的最终解,最优值所构建的是动态规划问题的解空间,我们需要根据这个解空间来最终构造出最优解。

     最大公共子序列问题的最优解结构用递归方程描述如下, 表示的是字符序列 和字符序列的最大公共子序列元素个数。注意,公式条件中  中的下标代指实际问题中字符序列X和字符序列Y的实际元素个数。在程序实现时,由于字符数组下标是从0开始,所以实际指代的是字符数组中的元素  。



这是问题的关键,有了它,我们可以构建出问题的最优值解空间。下图是以给定的字符数组 a, b,构建的最优值解空间


char[] a = {'A','C','D','E','H','L'};
char[] b = {'A','B','C','I','F','H','L'};




有了最优值解空间后,我们可以通过回溯把问题的最优解求出。



上图中着色的单元格是求解过程中所经过的路径,黄色的为最优解的元素,即最大公共子序列,绿色的部分为非公共子序列元素。


代码实现

public class CLS {

	
	private void commonCLS(char[] a,char[] b){
		
		int i,j;
		int[][] c = new int[a.length + 1][b.length + 1]; //构建最优值解空间。
		for ( i = 0 ;i <= a.length ;i++) c[i][0] = 0;
		for ( j = 0 ;j <= b.length; j++) c[0][j] = 0;
		for (i = 1 ;i <= a.length ;i++)
			for (j = 1;j <=b.length; j++){
				if (a[i - 1] == b[j - 1]) //由于数组元素下标从零开始,故实际需要查看数组中的a[i-1] 和 b[j-1]。
				   {c[i][j] = c[i - 1][j - 1] + 1;}
				else
				{
					if (c[i - 1][j] >= c[i][j - 1]) 
						c[i][j] = c[i-1][j];
					else
						c[i][j] = c[i][j - 1];
				}
			}
		constructSolution(a.length,b.length,a,b,c);
	}
	
	private void constructSolution(int i,int j,char[] a,char[] b,int[][] c){
		if ( i == 0 || j == 0) return;
		if (c[i][j] == c[i-1][j-1] + 1 && a[i-1] == b[j-1]){ //由于数组元素下标从零开始,故实际需要查看数组中的a[i-1] 和 b[j-1]。
		    constructSolution(i-1,j-1,a,b,c);
			System.out.print(a[i-1] + " ");
		}else
		{
		if (c[i - 1][j] >= c[i][j-1]) 
			constructSolution(i-1,j,a,b,c);
		else
			constructSolution(i,j-1,a,b,c);
		}
			
	}
	

	public static void main(String[] args) {
		
		char[] a = {'A','C','D','E','H','L'};
		char[] b = {'A','B','C','I','F','H','L'};
		
		CLS cls = new CLS();
		cls.commonCLS(a, b);


	}

}

输出结果

A C H L 

        对于最大公共字串,其最优解空间要相对简单,由于其要求子串的小标在两个字符数组中都是连续的,那么问题的最优解就会在二维矩阵解空间的斜对角线上。其最优解结构的递归方程式可描述如下


        最大公共子序列问题的最优解结构用递归方程描述如下, 表示的是字符序列 和字符序列的最大公共子串元素个数。注意,公式条件中  中的下标代指实际问题中字符序列X和字符序列Y的实际元素个数。在程序实现时,由于字符数组下标是从0开始,所以实际指代的是字符数组中的元素  。

        同样以最大公共子序列用到的字符数组 a, b为例,构建的最优值解空间如下


char[] a = {'A','C','D','E','H','L'};
char[] b = {'A','B','C','I','F','H','L'};

不难看出上述最优值解空间中构造出的最优解如下图


        另外  ,我们通过上述最优值解空间去求最优解的话,我们还需要一个坐标点位置,就是从那里开始回溯来最优解。因为对于给定的不同字符串,生成的最优值解空间也会不一样,我们要找到所有斜对角线上最长且连续的一串自然数,就需要记录下其一端的坐标 点p (x,y)。对于当前给定的a,b字符数组,坐标点p的位置为x=6,y=7。

代码如下

public class SequentialLCS {
	
	
	private void sLCS(char[] a,char[] b){
		int sum = 0;
		int m=0,n=0;
		int[][] c = new int[a.length + 1][b.length + 1];
		for (int i=0;i<=a.length;i++) c[i][0] = 0;
		for (int j=0;j<=a.length;j++) c[0][j] = 0;
		for (int i=1;i<=a.length;i++)
			for (int j=1;j<=b.length;j++){
				if (a[i-1] == b[j-1]) //由于数组元素下标从零开始,故实际需要查看数组中的a[i-1] 和 b[j-1]。
					c[i][j] = c[i-1][j-1] + 1;
				else
					c[i][j] = 0;	
				if (sum < c[i][j]){
					sum  = c[i][j];
				    m = i;
				    n = j;
				}
			}

	   constructSolution(c,a,m,n);	
	}
	
	private void constructSolution(int[][] c, char[] a,int m, int n) {
		if ((m ==0 || n==0) ||(c[m][n] == 0)) return;
		constructSolution(c,a,m-1,n-1);
		System.out.print( a[m-1] + " ");
		
	}

	public static void main(String[] args){
		
		char[] a = {'A','C','D','E','H','L'};
		char[] b = {'A','B','C','I','F','H','L'};

		SequentialLCS sLCS = new SequentialLCS();
		sLCS.sLCS(a, b);
		

		
		
	}

}

运行结果如下

H L 




详解最长公共子序列问题(三种方法) C++分别利用三种动态规划解决最长公共子序列问题 阅读详情

相关推荐

数据结构与算法之最长公共子序列

数据结构与算法之最长公共子序列

weixin_47225948的博客 1833

最大公共子序列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、==最长公共子序列==(LCS)是什么?二、如何解决?1.分析问题2.递推公式3.构造最优解 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、最长公共子序列(LCS)是什么? 看一个例子:S1={1,5,2,8,9,3,6},S2={5,6,8,9,

J_pluto的博客 2989

动态规划——最长公共子序列(LCS)长度+路径输出

问题:例如:X={A,B,C,B,A,D,B},Y={B,C,B,A,A,C},那么,二者的最长公共子序列是{B,C,B,A},长度为4。 我们首先需要搞清楚以下两个概念: 最长公共子序列 VS 最长公共子串: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。 上述问题中的最长公共子序列与最长公共子串是一样的。 但是再举例X={A,B,C,B,A,D,B},Y={B,C,B,A,A,B},二者的最长公共子序列是{B,C,B,A,B},而二者的最长公共子

金州饿霸吃不饱的博客 659

最长公共子序列

动态规划:最长公共子序列,代码及其填写dp表格详解

北渡的博客 1万+

SAP SD核心流程解析:从销售订单到财务结算的实战指南

本文深入解析SAP SD模块从销售订单到财务结算的核心流程,重点剖析了销售订单中的行项目类别如何作为流程的“总开关”,决定了后续交货、开票及财务集成的走向。文章结合实战案例,详细拆解了正常销售、退货、第三方销售、寄售等典型流程的配置要点与国内化适配方案,并阐述了SD与财务模块集成的关键连接点,为顾问和用户提供了一份全面的实战指南。

weixin_29250403的博客 426

Robosuite实战:通过Xbox手柄实现机械臂6-DoF精准控制的完整指南

本文详细介绍了如何通过Xbox手柄实现机械臂的6-DoF精准控制,结合Robosuite仿真环境与MuJoCo物理引擎,提供从环境配置到代码实现的完整指南。文章重点解析了手柄映射原理、核心控制代码以及数据采集优化技巧,帮助开发者高效完成机械臂控制任务。

weixin_29169505的博客 419

利用动态规划和递归分别求两个串的最大公共子序列

利用动态规划和递归分别求两个串的最大公共子序列 相关代码/* * 求两个子串的最大公共子序列 */ public class Msin { /* * 1.利用递归的思想来处理的求最大公共子序列 */ public static int f(String str, String str2){ if(str.length() == 0

LuFei_java的博客 597

避坑指南:在Linux服务器上用Conda安装antiSMASH 5.2.0(解决Jinja2报错和Matplotlib权限问题)

本文详细介绍了在Linux服务器上使用Conda安装antiSMASH 5.2.0的避坑指南,重点解决了Jinja2报错和Matplotlib权限问题。通过创建专用conda环境、安装指定版本依赖包和配置缓存目录,帮助用户顺利完成antiSMASH的本地部署,适用于批量处理基因组分析任务。

weixin_26911099的博客 314

深刻理解最长公共子串、最长公共子序列(应该比较全面)

这里写自定义目录标题 理论知识: 推荐参考该博文:java实现字符串匹配问题之求两个字符串的最大公共子串 当然这篇也一样,看个人理解:求两个字符串的最长公共子串 图形理解: ...

3230

FreeSWITCH安装指南:三种部署方式解析与实践对比

Freeswitch部署方案比较:Yum安装简单快捷但灵活性差;源码安装可定制性强,适合深度开发和性能优化;Docker部署环境一致性好但网络配置复杂。生产环境推荐源码安装以获得最佳性能和定制能力,而Docker适合快速部署和扩展。不同方案各有利弊,需根据具体需求选择。

c_zyer的博客 2139

单细胞转录组分析(scRNA-seq)

单细胞转录组测序(Single-cell RNA sequencing,scRNA-seq)是一种高通量测序技术,可以在单细胞水平解析基因表达情况,揭示细胞异质性,探索稀有细胞类型,并研究细胞状态转换及动态调控机制。与传统的。

大甘的博客 6148

LintCode:79. 最长公共子串 VS 77. 最长公共子序列

最长公共子串与最长公共子序列的主要区别在于一个必须是连续的另一个则不一定。最长公共子串:题目:给出两个字符串,找到最长公共子串,并返回其长度。分析:这是一个经典的动态规划题,定义dp矩阵,dp[i][j]表示A串匹配到i,B串匹配到j时的最大公共长度。        dp有A.length()+1行,有B.length()列。第一行与第一列都为0;        有状态转移方程          ...

HxxxxxxU的博客 1638

LeRobot 入门教程(九)使用 Android、iOS 手机控制机械臂

本指南详细介绍了如何使用iOS/Android手机远程控制机器人。内容包括:1)安装依赖(pip install leroobot[phone]);2)平台支持说明(iOS需HEBI Mobile I/O应用/Android用WebXR);3)手机方向校准方法;4)控制模式设定(按钮/手势);5)示例脚本使用(遥操作/数据记录/回放/策略评估);6)关键参数配置(运动学/安全限制/夹爪控制);7)故障排查方法。支持ROS2集成,提供URDF文件处理、逆向运动学计算和实时可视化功能,适用于物理机器人和仿真环境

2506_90492529的博客 1656

最长公共子序列vs最长公共子串 Python3版本

最长公共子序列:给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共子序列,并返回其长度。 解题思路:定义dp[i][j]为字符串A的第一个字符到第i个字符串(A[:i])和字符串B的第一个字符到第j个字符(B[:j])的最长公共子序列。状态转移方程为: Python3代码如下: class Solution(object): def LCSeq(self, ...

章小幽的博客 548

电气:蒙特卡洛1000个风光场景并通过削减法|聚类法得到几个典型场景(matlab\python实现)

    个人电气目录传送门:学好电气全靠它,个人电气博文目录(持续更新中…)     本文内容包括22页(代码和一些自己对风光的观点) 提示:专栏解锁后,可以查看该专栏所有文章,划算。 文章目录一、理论依据1.风电DG出力概率模型1.2光伏DG出力概率模型1.3对风光的认识二、蒙特卡洛模拟1000个风光场景、并通过削减法得到5个典型风电场景 (Matlab 版程序)三、蒙特卡洛模拟1000个风光场景、并通过聚类法得到5个典型

总裁余(余登武)博客 7680

YOLO11改进策略【独家融合改进】| RCSOSA + SPD + WFU

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)和池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层和非步长卷积(non - strided convolution)层组成。WFU模块通过小波变换的频率分解与跨尺度融合机制,解决了传统上采样过程中的混叠和细节丢失问题,实现了高效、高保真的面部细节重建。

Limiiiing的博客 447

最长公共子串——动态规划求解

上篇总结了最长公共子序列用动态规划求解的问题,由此也引出了最长公共子串使用动态规划思想求解的问题。 再次辨析下两者的关系, 最长公共子序列 VS 最长公共子串: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。 其实话句话说最长公共子序列中包含着最长公共子串。 其实最长公共子串的算法求解思想与最长公共子序列的思路基本类似。 1.在最长...

weixin_30725467的博客 274

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

最长公共子序列 (LCS) vs 最长公共子串 二维 DP 核心区别

dp[i][j]以 s1 [i]、s2 [j] 为结尾的最长公共连续子串的长度。必须以当前两个字符结尾,天然约束「连续性」。字符不等直接归 0,体现连续性断裂;状态只依赖左上角;答案是整张 DP 表的最大值;DP 表中非 0 区域是连续斜向增长。dp[i][j]s1[1..i]和s2[1..j]的最长公共子序列长度。关键:不要求结尾字符匹配,只看两个前缀整体的最优解。字符不等时取上方 / 左方最大值,允许跳过字符(对应子序列不连续);上、左、左上三个方向;答案就是 DP 表。

weixin_48309090的博客 145

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

matlab最长公共子问题,Python之最长公共子序列 VS 最长公共子串[动态规划]

全文参考均如下博文。1、最长公共子序列(Longest Common Subsequence,LCS):在字符串A和字符串B中都出现的序列,且顺序与母串保持一致最长的那个序列。2、最长公共子串(Longest Common Substring):相比LCS更加严格,序列必须连续出现,即公共的子字符串。eg: csdnblog与belong,最长公共子序列为blog,最长公共子串为lo。 def...

weixin_31642161的博客 353

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

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

1. 什么是 LCSs?   什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence)和最长公共子串(Longest-Common-Substring)问题。这两个问题非常的相似,所以对不熟悉的同学来说,有时候很容易被混淆。下面让我们去好好地理解一下两者的区别吧。 1.1 子...

weixin_33932129的博客 870

2017第八届C/C++B组省赛——最大公共子串

标题:最大公共子串最大公共子串长度问题就是:求两个串的所有子串中能够匹配上的最大长度是多少。比如:"abcdkkk" 和 "baabcdadabc",可以找到的最长的公共子串是"abcd",所以最大公共子串长度为4。下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。请分析该解法的思路,并补全划线部分缺失的代码。#include &lt;stdio.h&gt;#includ...

越努力,越幸运!!! 530

求最长子序列和最长公共子串

又有一段时间没刷题,今天温故下,最长公共子序列和最长公共子串概念不一样,子序列可以不连续,子串必须连续,这两题均可以用动态规划解决!,下面程序在VS上跑过无问题! #include&amp;lt;iostream&amp;gt; #include&amp;lt;string&amp;gt; #include&amp;lt;algorithm&amp;gt; #include&amp;lt;cmath&amp;gt; using namespac

syyyy712的博客 283

[LeetCode解题] -- 动态规划二 [ 子串、子序列问题 ]

子序列 vs 子串、子数组、子区间 子序列 : 可以不连续 子串、子数组、子区间 : 必须连续 1.最大连续子序[ 子数组]和 53. 最大子序和 [ 题目描述 ] 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释:连续子数组[4,-1,2,1] 的和最大,为6。 进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解...

zhanggf的博客 773

python实现求字符串最长公共子串

本文主要参考http://www.cnblogs.com/ider/p/longest-common-substring-problem-optimization.html的讲解,本人自己用python实现了一下暴力法,动态规划。 # coding: utf-8# ## 最长公共子串问题 # # ### 暴力法求解 VS 动态规划 # # ### 参考自http://www.cnblogs.

silence2015的专栏 5367

最长公共子序列——动态规划

问题 例如:X={A,B,C,B,A,D,B},Y={B,C,B,A,A,C},那么,二者的最长公共子序列是{B,C,B,A},长度为4。 我们首先需要搞清楚以下两个概念: 最长公共子序列 VS 最长公共子串: 找两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。而最长公共子序列则并不要求连续。 上述问题中的最长公共子序列与最长公共子串是一样的。 但是再举例X={A,B,C,B,A,D,...

qq_43633063的博客 622
上一篇: 分布式事务中的两阶段提交
下一篇: Java 在 Oracle BPM 中的用武之地
TechNerd
博客等级 码龄14年 5粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值