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

article/2025/9/6 15:40:36

本题与力扣主站1143题相同.

一.问题描述

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
确切地说,若给定序列X=<x1, x2,…, xm>,则另一序列Z=<z1, z2,…, zk>是X的子序列是指存在一个严格递增的下标序列 <i1, i2,…, ik>,使得对于所有j=1,2,…,k有
image-20211028094154836

例如,序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2, 3, 5, 7>。

给定两个序列XY,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例: X=<A, B, C, B, D, A, B>
Y=<B, D, C, A, B, A>
Z1=<B, C, A>
Z2= <B, C, B, A>
Z1和Z2是X和Y的一个公共子序列,而且Z2是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。(不唯一!)

最长公共子序列(LCS)问题:给定两个序列X=<x1, x2, …, xm>和Y=<y1, y2, … , yn>,要求找出X和Y的一个最长公共子序列。

二.解题思路

穷举搜索法:对X的每一个子序列,检查它是否也是Y的子序列,并选出最长的公共子序列。X的一个子序列相应于下标序列{1, 2, …, m}的一个子序列,因此,X共有2m个不同子序列,从而穷举搜索法需要指数时间。

下面我们来考虑用动态规划法解最长公共子序列问题.此问题是动态规划的典型应用之一.

1.分析最优解的结构

定理:LCS具有最优子结构
设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>,则:

  • 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
  • 2.若xm≠yn 且 zk≠xm ,则Z是Xm-1和Y的最长公共子序列;
  • 3.若xm≠yn 且 zk≠yn ,则Z是X和Yn-1的最长公共子序列。

其中Xm-1=<x1, x2, …, xm-1>,Yn-1=<y1, y2, …, yn-1>,Zk-1=<z1, z2, …, zk-1>。

证明如下(反证法):

  • 已知xm=yn ,假如zk≠xm,则<z1, z2, …, zk ,xm >是X和Y的长度为k十1的公共子序列。
    这与Z是X和Y的一个最长公共子序列矛盾。因此,必有zk=xm=yn.Zk-1是Xm-1和Yn-1的一个长度为k-1的公共子序列。若Xm-1和Yn-1有一个长度大于k-1的公共子序列W,则将xm加在其尾部将产生X和Y的一个长度大于k的公共子序列。此为矛盾。
    故Zk-1是Xm-1和Yn-1的一个最长公共子序列。
  • 已知xm≠yn, zk≠xm ,Z是Xm-1和Y的最长公共子序列。假如Z不是Xm-1和Y的最长公共子序列。
    zk≠xmàZ是Xm-1和Y的一个公共子序列. 若Xm-1和Y有一个长度大于k的公共子序列W,则W也是X和Y的一个长度大于k的公共子序列。这与Z是X和Y的一个最长公共子序列矛盾。由此即知Z是Xm-1和Y的一个最长公共子序列。
  • 与2类似。

这说明:两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列。因此,最长公共子序列问题具有最优子结构性质。

2.建立递归关系

由最长公共子序列问题的最优子结构性质可知,要找出X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的最长公共子序列,可按以下方式递归地进行:

  • 当xm=yn时,{Xm-1和Yn-1的最长公共子序列}的末尾加上 xm
  • 当xm≠yn时,Max{Xm-1和Y的一个最长公共子序列,X和Yn-1的一个最长公共子序列}

由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。例如,在计算X和Y的最长公共子序列时,可能要计算出X和Yn-1及Xm-1和Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1和Yn-1的最长公共子序列。

根据子问题的最优值的递归关系,我们用c[i,j]记录序列Xi和Yj的最长公共子序列的长度。其中Xi=<x1, x2, …, xi>,Yj=<y1, y2, …, yj>。当i=0或j=0时,空序列是Xi和Yj的最长公共子序列,故c[i,j]=0。其他情况下,可建立递归关系如下:
在这里插入图片描述

3.计算最优值

直接利用(2.2)式容易写出一个计算c[i,j]的递归算法,但其计算时间是随输入长度指数增长的。由于在所考虑的子问题空间中,总共只有θ(m*n)个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率。

  • c[i,j]存储Xi与Yj的最长公共子序列的长度,X和Y的最长公共子序列的长度记录于c[m,n]中
  • b[i,j]记录指示c[i,j]的值是由哪一个子问题的解达到的,这在构造最长公共子序列时要用到.
4.构建最长公共子序列

LCS_length产生数组b用于构造序列<x1 …, xm>和<y1, …, yn>的最长公共子序列。
首先从b[m,n]开始,沿着其中的箭头所指的方向在数组b中搜索。

  • 当b[i,j]="1"时,表示Xi与Yj的最长公共子序列是由Xi-1与Yj-1的最长公共子序列在尾部加上xi得到的子序列;
  • 当b[i,j]="2"时,表示Xi与Yj的最长公共子序列和Xi-1与Yj的最长公共子序列相同;
  • 当b[i,j]="3"时,表示Xi与Yj的最长公共子序列和Xi与Yj-1的最长公共子序列相同。

代码如下:

// // 最长公共子序列
#include<bits/stdc++.h>
using namespace std;
const int Size = 1010;   //尽量用全局变量
int DP[Size][Size];
int DIR[Size][Size];    
int LCS_length(string a, string b)
{int M = a.size();int N = b.size();for(int i=1; i<=M; i++){for(int j=1; j<=N; j++){if(a[i-1] == b[j-1]) {DP[i][j] = DP[i-1][j-1] + 1;DIR[i][j] = 1;}else if(DP[i-1][j] >= DP[i][j-1]){DP[i][j] = DP[i-1][j];DIR[i][j] = 2;}else{DP[i][j] = DP[i][j-1];DIR[i][j] = 3;}}}return DP[M][N];
}
void LCS(string a, int i, int j)
{if(i==0 || j==0) return;if(DIR[i][j] == 1) {LCS(a, i-1, j-1);cout<<a[i-1];  //a[i-1]==b[j-1]}else if(DIR[i][j]==2) LCS(a, i-1, j);else if(DIR[i][j]==3) LCS(a, i, j-1);
}
void LCS2(string a, string b, int i, int j)  //算法改进,不使用DIR数组,仅仅依靠DP数组以及a,b两个序列
{if(i==0 || j==0) return;if(a[i-1]==b[j-1]){LCS2(a, b, i-1, j-1);cout<<a[i-1]<<endl;}else if(DP[i-1][j] > DP[i][j-1]) LCS2(a, b, i-1, j);else LCS2(a, b, i, j-1);
}
int main()
{string a, b;cout<<"请输入两个字符串:"<<endl;while(cin>>a>>b && a!="GG"){cout<<"最大公共子序列长度为:"<<LCS_length(a, b)<<endl;// LCS(a, a.size(), b.size());cout<<"最大公共子序列为:";LCS2(a, b, a.size(), b.size());cout<<endl<<"请输入两个字符串:"<<endl;}system("pause");return 0;
}
//www.pgcode.top 版权所有

运行结果:
在这里插入图片描述

本篇文章参考我的老师毕方明《算法设计与分析》课件.
欢迎大家访问个人博客—乔治的编程小屋,和我一起为大厂offer努力吧!


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

相关文章

知识图谱本体建模之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教程。 本…

动态本体 palantir

102解析器与106本体耦合&#xff0c;106本体与108数据库耦合&#xff1b; 106本体有一个或多个110对象类型和116属性类型 110对象类型实例化多个112对象 每一个对象有一个或多个属性 116属性类型实例化114A和114B属性 116属性类型有一个或多个118组件&#xff0c;组件有字符串、…

什么是计算机科学中的“本体论”

最近看用户画像&#xff0c;里面提到了本体论。故把知乎一个回答放于此地。 一、本体的概念 本体的概念有两层意思&#xff0c;一层是哲学层面的意思&#xff0c;一层是引申到信息科学中的语义层面的意思。 举个最通俗的例子来解释一下这两层意思&#xff0c;我们就拿苹果来举…

本体建模学习笔记

目录 1. 语义网 & 语义网络 1.1 链接数据与知识图谱 的区别 1.2 本体构建的两种方式 1.3 知识图谱数据的来源 0. RDF、OWL 与RDFS 0.1 RDF序列化 0.2 关系 / 属性 0.3 RDFS词汇 0.4 本体映射词汇&#xff08;Ontology Mapping&#xff09; 2. Protege实现本体建模…

知识元与知识本体

元数据&#xff08;Metadata&#xff09;就是“关于数据的数据”,是对数据进行组织和处理的基础。元数据法就是对信息单元及其集合进行规范描述从而形成元数据&#xff0c;并依其将分布式的信息资源整合成有机信息体系的基准、方法和工具。主题词表&#xff1a;也称叙词表。它是…

本体语言 OWL

万维网本体语言OWL2 文章目录 万维网本体语言OWL2一、引言二、本体语言的需求三、OWL2和RDF/RDFS的兼容性3.1 OWL2 Full&#xff1a;基于RDF的语义3.2 OWL2 DL&#xff1a;直接语义 四、OWL语言五、OWL2 概要六、实验 OWL的构造七、总结 一、引言 通俗的讲&#xff0c;RDF被限…

本体概述

目录1.定义2.本体的目标和作用3.本体构成要素4.领域本体与上层本体5.本体语言6. 构造Ontology 的规则 7.本体在信息检索的应用 1.定义 – 1991/Neches 等&#xff1a;给出构成相关领域词汇的基本术语和关系&#xff0c;以及利用这些术语和关系构成的规定这些词汇外延的规则…

本体 摘抄笔记

一、本体的一些介绍 &#xff08;来源&#xff1a;https://blog.csdn.net/shendeguang/article/details/8241164&#xff09; 1. 本体论语义学的特点&#xff1a; 本体论语义学与其他人工智能理论、自然语言加工系统相比有自己的一些鲜明特点。 其一&#xff0c;它强调对意义…

图构建:领域本体设计原则与动态本体

图构建&#xff1a;领域本体设计原则与动态本体 前文《思考总结&#xff1a;领域知识图谱平台构建与业务应用》中提到&#xff1a;“本体设计是图应用中的重中之重&#xff0c;一切的图展示、图计算、图分析、图挖掘、图模式匹配…的基础在图构建&#xff0c;而图构建的核心是…

常用本体建模工具

常用本体建模工具&#xff1a; Apollo、OntoStudio、TopBraid Composer、Semantic Turkey、Knoodl、Chimaera、OliEd、WebODE、Kmgen和DOME Protg Protg[1]是一款由斯坦福大学编写并维护的开源本体建模和编辑工具&#xff0c;其支持Web版本和PC版本&#xff0c;使用OWL语言…

本体(Ontology)

我是在撰写毕业论文中接触到知识表示方面的内容&#xff0c;有时需要理论与实践相结合&#xff0c;关于这方面的理论知识学习&#xff0c;除了网页资料、书籍、另外推荐一个网站&#xff1a;熊猫学术(https://sc.panda321.com/)&#xff0c;可以查阅很多相关的学术论文&#xf…

知识图谱初步学习(一)——本体+Protege新手学习

文章目录 前言&#xff08;本体详解&#xff09;1.本体概念2.本体分类3.本体组成4.本体构建方法5.本体构建的原则6.本体应用 一、protege简介二、软件使用步骤1.安装2.使用3.案例 三、问题解决方案汇总 前言&#xff08;本体详解&#xff09; 在开始学习知识图谱的过程中&…

本体调研

1.1本体概念 本体是用于描述一个领域的术语集合&#xff0c;其组织结构是层次结构化的&#xff0c;可以作为一个知识库的骨架和基础。 本体不等同于个体&#xff0c;它是相应领域内公认的概念集合。 1.2 本体分类 依照领域依赖程度: &#xff08;1&#xff09;顶层本体&…

知识图谱初步学习(零)——本体是什么

知识图谱初步学习&#xff08;零&#xff09;——本体是什么 文章目录 知识图谱初步学习&#xff08;零&#xff09;——本体是什么前言一、 哲学层面理解二、 引申到语义层面理解三、学术层面四、其他层面- 术语- 语义网 五、本体与类、本源、实体、符号的区别六、用语义三角形…

本体(Ontology)概述

认识本体 本体&#xff08;Ontology&#xff09;的概念源自于哲学领域&#xff0c;在哲学中的定义为“对世界上客观事物的系统描述&#xff0c;即存在论”。哲学中的本体关心的是客观现实的抽象本质。而在计算机领域&#xff0c;本体可以在语义层次上描述知识&#xff0c;可以看…

区块链 Vs. 互联网,创新在哪里?

本文转载自共识未来公众号 引言&#xff1a;最近关于区块链革命的提法少了很多&#xff0c;我们很少再听到“区块链即将颠覆互联网”的提法&#xff0c;这似乎也寓意着区块链技术&#xff08;加密技术&#xff09;正在进入一个理性发展的阶段&#xff0c;如果按照Gartner的技术…

js提交form表单

【背景】 前段时间将边用边学javascript.pdf书看完了,其中之前最不熟悉的也是这次印象最深刻的就是提交form表单,所以在这里总结一下js提交form表单,以及表单中对应的一些扩展知识O(∩_∩)O~ 【概念】 表单在网页中主要负责数据采集功能;一个表单偶三个基本组成部分&am…

JavaScript笔记-点击button提交form表单

功能如下&#xff1a; 点击购买后&#xff0c;点击确定。 确定调用了一个js函数&#xff0c;提交form表达给后端 代码如下&#xff1a; <div class"modal-footer"><button type"button" class"btn text-white border bg-dark" data-b…