最长公共子序列 - LCS

article/2025/9/5 13:43:04

最长公共子序列 - LCS

  • 问题描述
    • 子序列定义
    • 子串定义
    • 公共子序列定义
    • 最长公共子序列(以下简称LCS)
  • 动态规划解决
    • 子问题划分及依赖关系
    • 递推公式
  • 伪代码
  • 代码实现
  • 复杂度分析

问题描述

子序列定义

给定一个序列X=<x1,x2,x3,x4…,xm>,另一个序列Z=<z1,z2,z3,z4…,zk>,若存在一个严格递增的X的下标序列<i1,i2,i3,…,ik>对所有的1,2,3,…,k,都满足x(ik)=zk,则称Z是X的子序列

比如Z=<B,C,D,B>是X=<A,B,C,B,D,A,B>的子序列

子串定义

子串的话与子序列不同,子串要求必须连续。

例如
BCDB 虽然是X=<A,B,C,B,D,A,B>的子序列
但不是它的字串 因为BCDB不连续。
BCBD属于<A,B,C,B,D,A,B>的字串

该篇文章我们要求的是 子序列 而不是 子串

公共子序列定义

如果Z既是X的子序列,又是Y的子序列,则称Z为X和Y的公共子序列

最长公共子序列(以下简称LCS)

2个序列的公共子序列中长度最长的那个

动态规划解决

子问题划分及依赖关系

在这里插入图片描述

递推公式

在这里插入图片描述

伪代码

在这里插入图片描述
利用标记函数追踪解:
在这里插入图片描述

在这里插入图片描述

代码实现

public class LCS {public static void main(String[] args) {String x = "ABCBDAB";String y = "BDCABA";int m = x.length();int n = y.length();// 动态数组int[][] c = new int[m+1][n+1];// 标记函数数组int[][] b = new int[m+1][n+1];// 上边界赋值为0for (int i=0; i<=n; i++) {c[0][i] = 0;b[0][i] = 0;}// 左边界赋值为0for (int i=0; i<=m; i++) {c[i][0] = 0;b[i][0] = 0;}System.out.println("字符串1:" + x);System.out.println("字符串2:" + y);LCSlength(m, n, x, y, c, b);System.out.println("x,y 的最长公共子序列长度为:" +  c[m][n]);// 倒序输出 公共子序列System.out.println("倒序输出 公共子序列:");LCS(m, n, b, x);}/*** 最长公共子序列*/public static void LCSlength(int m, int n, String x, String y, int[][] c, int[][] b) {for (int i=1; i<=m; i++) {for (int j=1; j<=n; j++) {if (x.charAt(i-1) == y.charAt(j-1)) {   // 若字符相同 c[i][j] = c[i-1][j-1] + 1;c[i][j] = c[i-1][j-1] + 1;b[i][j] = 1;    // 1 代表 ↖} else if (c[i][j-1] > c[i-1][j]) { // 字符不同取最大 c[i][j] = max(c[i][j-1], c[i-1][j])c[i][j] = c[i][j-1];b[i][j] = 2;    // 2 代表 ←} else {c[i][j] = c[i-1][j];b[i][j] = 3;    // 3 代表 ↑}}}// 输出所填表System.out.println("输出所填动归表:");for (int i=0; i<=m; i++) {for (int j=0; j<=n; j++) {System.out.print(c[i][j] + " ");}System.out.println();}}/*** 输出 最长公共子序列 倒序输出* @param i* @param j* @param b:标记函数数组* @param x:x字符串*/public static void LCS(int i, int j, int[][] b, String x) {if (i==0 || j==0) {return;}//  1 表示 ↖if (b[i][j] == 1) {System.out.print(x.charAt(i-1) + " ");// 输出该字符LCS(i-1, j-1, b, x);} else if (b[i][j] == 2) {  // 2 表示 ←LCS(i, j-1, b, x);} else {                    // 3 表示 ↑LCS(i-1, j, b, x);}}
}

输出结果:

在这里插入图片描述

复杂度分析

在这里插入图片描述
时间复杂度: O(mn) 两层循环
空间复杂度: O(mn) 需要一个二维数组的表格


http://chatgpt.dhexx.cn/article/FuV1TRXm.shtml

相关文章

最长公共子序列C++实现

给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;也可以不删除任何字符&#xff09;后组成的新字符串。 …

最长公共子序列动态规划c语言,动态规划----最长公共子序列(C++实现)

最长公共子序列 题目描述:给定两个字符串s1 s2 … sn和t1 t2 … tm 。求出这两个字符串的最长公共子序列的长度。字符串s1 s2 … sn的子序列指可以表示为 … { i1 < i2 < … < ik }的序列。 输入样例 2 asdf adfsd 123abc abc123abc 输出样例 3 6 解题思路: 这道题…

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

掌握动态规划求解问题的思想&#xff1b;针对不同的问题&#xff0c;会利用动态规划进行设计求解以及时间复杂度分析&#xff0c;并利用JAVA/C/C等编程语言将算法转换为对应的程序上机运行&#xff08;语言自选&#xff09;。 理解两组序列的最长公共子序列问题&#xff0c;能…

求取最长公共子序列

前言 LCS可以描述两段文字之间的“相似度”&#xff0c;即它们的雷同程度&#xff0c;从而能够用来辨别抄袭。另一方面&#xff0c;对一段文字进行修改之后&#xff0c;计算改动前后文字的最长公共子序列&#xff0c;将除此子序列外的部分提取出来&#xff0c;这种方法判断修改…

最长公共子序列长度

求两个字符串的最长公共子序列长度。 输入格式: 输入长度≤100的两个字符串。 输出格式: 输出两个字符串的最长公共子序列长度。 输入样例1: ABCBDAB BDCABA输出样例1: 4输入样例2: ABACDEF PGHIK输出样例2: 0 (1条消息) HBU训练营【动态规划DP】——最长公共子序列长…

最长公共子序列算法 java,算法学习——java实现最长公共子序列,

算法学习——java实现最长公共子序列学习——java实现最长公共子序列的算法&#xff0c; 实验目的&#xff1a; 输入两个同类型的序列&#xff0c;用动态规划的方法计算它们最长的公共子序列的长度和序列。 (推荐教程&#xff1a; Java视频教程 思考&#xff1a; 1.首先&#x…

动态规划解最长公共子序列(LCS)(附详细填表过程)

目录 相关概念 子序列形式化定义&#xff1a; 公共子序列定义&#xff1a; 最长公共子序列&#xff08;以下简称LCS&#xff09;&#xff1a; 方法 蛮力法求解最长公共子序列&#xff1a; 动态规划求解最长公共子序列&#xff1a; 分析规律&#xff1a; 做法&#xff…

最长公共子序列问题 c语言,最长公共子序列问题C语言

最长公共子序列问题C语言 #include#include#includeint num[50][50]{0}; int b[50][50]{0}; int lcsLength(char *x,char *y,int xLen,int yLen); void LCS(int i,int j,char *x); int lcsLength(char *x,char *y,int xLen,int yLen){ int mxLen-1; int nyLen-1; for(int i0;i&…

java最长公共子序列算法_算法学习——java实现最长公共子序列

实验目的&#xff1a; 输入两个相同类型的序列&#xff0c;用动态规划方法计算他们的最长公共子序列的长度以及序列。 思路&#xff1a; 1、先用一个二维数组存储最长公共子序列的长度&#xff0c;还要记录每个值的状态 2、根据记录值的状态&#xff0c;递归回溯求出最长公共子…

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

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

算法:最长公共子序列(输出所有最长公共子序列)

问题描述&#xff1a;给定两个序列&#xff0c;例如 X “ABCBDAB”、Y “BDCABA”&#xff0c;求它们的最长公共子序列的长度。 下面是求解时的动态规划表&#xff0c;可以看出 X 和 Y 的最长公共子序列的长度为4&#xff1a; 输出一个最长公共子序列并不难&#xff08;网上…

动态规划 最长公共子序列 过程图解

1.基本概念 首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。什么是子串呢?给定串中任意个连续的字符…

算法知识之最长公共子序列问题(动态规划)

最近朋友让帮做个关于动态规划的最长公共子序列的问题,翻看以前的笔记并完成该题后,顺便写这样一篇文章,希望对大家有所帮助,同时也帮助自己回顾该知识点. 一.最长公共子序列的定义 子序列:若给定序列X{x1,x2,…,xm},则另一序列Z{z1,z2,…,zk},是X的子序列是指存在一个严格递…

动态规划篇——最长公共子序列(c++)

引言&#xff1a;最长公共子序列属于动态规划的基础篇&#xff0c;由字符串的最长公共最序列可以引出很多的问题。 最长子序列详细讲解以及练习题目 需要详细讲解教程的可以观看上面链接的文章&#xff0c;以下是自己做的简单的概括。 一、何为最长公共子序列 A和B的公共子序…

最长公共子序列(LCS)

此文全文参考自&#xff1a;https://blog.csdn.net/dq_dm/article/details/45043689&#xff0c;特此感谢&#xff01; 然后自己参考了&#xff1a;http://www.ahathinking.com/archives/115.html 和July的ppt讲义《十分钟搞定LCS》&#xff0c;为表示版权&#xff0c;特地留下…

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

先来讲解以下什么是最长公共子序列。最长公共子序列不是最长相同字符串&#xff0c;有点相似但不一样&#xff0c;来举个简单的例子&#xff0c;有字符串s1bcdea&#xff0c;s2abce&#xff0c;最长相同字符串是bc&#xff0c;最大公共部分是2&#xff1b;而最长公共子序列则是…

动态规划---例题2.最长公共子序列问题

本题与力扣主站1143题相同. 一.问题描述 一个给定序列的子序列是在该序列中删去若干元素后得到的序列。 确切地说&#xff0c;若给定序列X<x1, x2,…, xm>&#xff0c;则另一序列Z<z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 <i1, i2,…, ik&g…

知识图谱本体建模之RDF、RDFS、OWL详解

&#xff08;一&#xff09;知识图谱本体建模之RDF、RDFS、OWL详解 1.语义网体系 知识图谱于2012年由Google提出&#xff0c;并不是新概念&#xff0c;而是由语义网络(Semantic Network)衍生而来。语义网络由相互连接的节点和边组成&#xff0c;节点表示概念或者对象&#xf…

OWL本体基础知识

备注&#xff1a; OWL本体中对象属性和数据属性都可以有进一步的注释属性&#xff0c;被称之为公理 <owl:NamedIndividual rdf:about"http://www.semanticweb.org/bob/ontologies/2022/11/untitled-ontology-20#刘二菲"><like rdf:resource"http://www…

protege系列(一):本体开发101:创建第一个本体的指南

protege作为领域本体编辑工作一直为自然语言处理和语义网、知识图谱等行业人士喜爱&#xff0c;但是还没有比较完整的官方Protege中文文档&#xff0c;本系列旨在通过对protege官方网站上教程等内容的翻译和再现&#xff0c;为广大网友提供一个全面的、权威的protege教程。 本…