输出所有最长公共子序列

输出所有最长公共子序列

  • 什么是最长公共子序列
  • 过程讲解
  • 完整程序代码(python)

什么是最长公共子序列

在力扣题库中的1143题有一道最长公共子序列,但是那个只是返回最长子序列的长度,而没有输出所有的最长子序列
在这里插入图片描述
通过上图中的举例我们可以看出子序列是可以不连续的但是前后关系是不能变的

过程讲解

链接: b站一个关于最长子秩序的讲解视频
在这里插入图片描述

我们假设两个序列 s1 = "abcbdab"s2 = "bdcabc"去求它们两个的最长公共子序列
首先我们假定D[ i ][ j ]的值是s1前 i 个字符和s2前 j 个字符的LCS(最长公共子序列)
首先讨论D[i][j]的值

  1. 如果s1的第 i 个字符和s2的第 j 个字符相等那么D[ i ][ j ]等于s1前 i-1 个字符和s2前 j-1 个字符的LCS的值加 1 即D[ i ][ j ] = 1+D[ i-1 ][ j-1 ]
  2. 如果s1的第 i 个字符和s2的第 j 个字符不相等那么D[ i ][ j ]等于s1前 i-1 个字符和s2前 j 个字符的LCS的值和s1前 i 个字符和s2前 j-1 个字符的LCS的值中的最大值。
  3. 如果 i 或 j 等于0那么此时 D[ i ][ j ] = 0,因为 i 和 j 其中一个为0的话就是一个空序列,那么空序列与其他序列的最长公共子序列为0.

那么根据上述描述的关系就可以构建 D[ i ][ j ]
在这里插入图片描述
序列 s1 = "abcbdab"s2 = "bdcabc"的长度分别为7和6那么我们构建的二维数组D应该是8*7的因为这样我们才能使D[ i ][ j ]的值是s1前 i 个字符和s2前 j 个字符的LCS(最长公共子序列)

  1. 首先在第0行和第0列肯定都是0,因为是我们上面讨论的第三条
  2. 然后看第1行第1列,s1中的字符与s2中的字符不相等所以取左边和上边的最大值,是我们上面讨论的第二条所以这里为0
  3. 然后同理第第1行第2列与第1行第3列都是0,在第1行第4列时,s1中的字符与s2中的字符相等所以此处的值为D[ i-1 ][ j-1 ]的值+1,是我们上面讨论的第一条
  4. 然后再看第1行第5列s1中的字符与s2中的字符不相等所以取左边和上边的最大值,所以此处值为1,其他的类似直到把这个二维矩阵填满。

回溯输出所有最长公共子序列
在这里插入图片描述
回溯时从最后二维数组的最后一个值开始,这个值就是我们的最长子序列的长度

  1. 首先看当前m行n列中s1[ m-1 ]与s2[ n-1 ]的值是否相等,如果相等则这个值就是我们最长子序列中的值
  2. 如果当前m行n列中s1[ m-1 ]与s2[ n-1 ]的值不相等,则比较左边和上方的值哪个和现在的值相等,相等则说明当前下标的值是从它过来的
  3. 当m行n列中s1[ m-1 ]与s2[ n-1 ]的值不相等且左边和上方的值相等时,需要在此处分叉,因为当前的值可以从它们两个中的任意一个过来

完整程序代码(python)

代码参考:链接: 【动态规划】输出两个序列的所有的最长公共子序列(java)

class Solution:
    def __init__(self, text1: str, text2: str):
        self.text1 = text1	#输入第一个序列
        self.text2 = text2	#输入第二个序列
        self.m, self.n = len(text1), len(text2)	#m,n分别代表第一个序列和第二个序列的长度
        self.arr = [[0 for j in range(self.n+1)] for i in range(self.m+1)]  # 创建一个m*n的矩阵c并初始化元素为0
        self.set1 = set()		#创建一个集合用来存储所有的最长子序列
        for i in range(1,self.m + 1):	#用两个for循环来对二维矩阵arr填值
            for j in range(1,self.n+ 1):
                if self.text1[i-1] == self.text2[j-1]:	#两个序列当前值相等的话取i-1和j-1的值+1,我们讨论的第一条
                    self.arr[i][j] = self.arr[i-1][j-1]+1
                else:									#不相等的话取左边和上边的最大值,我们讨论的第二条
                    self.arr[i][j] = max(self.arr[i][j-1],self.arr[i-1][j])
        print(self.arr)						#打印一下这个二维数组

    def longestCommonSubsequence(self,i,j,s):#i是行,j是列,s是字符串
        while i>0 and j>0:							#回溯
            if self.text1[i-1] == self.text2[j-1]:		#回溯中的第一个
                s += self.text1[i-1]
                i -= 1
                j -= 1
            elif self.arr[i-1][j] > self.arr[i][j-1]:	#回溯中的第二个
                i -= 1
            elif self.arr[i-1][j] < self.arr[i][j-1]:	#回溯中的第二个
                j -= 1
            else:										#最后一种情况就是回溯中讨论的第三个出现分叉
                self.longestCommonSubsequence(i-1, j, s)
                self.longestCommonSubsequence(i, j-1, s)
                break;									#分叉后让当前跳出循环,让两条分叉去分别递归
        if len(s) == self.arr[-1][-1]:					#如果当前回溯的字符串长度等于最长子序列的长度则把它加入到集合中
            self.set1.add(s[::-1])


print("请输入第一个序列")
list1 = input()			#读取第一个列表
print("请输入第二个序列")
list2 = input()			#读取第二个列表
s1 = Solution(list1,list2)	#创建一个对象
s1.longestCommonSubsequence(len(list1),len(list2),"")	#调用最长子序列的函数
print(s1.set1)		#输出集合中所有的最长子序列

#abcbdab
#bdcabc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/123435.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python制作采集直播弹幕小软件

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用: Python 3.8 Pycharm模块使用: import requests >>> pip install requests import time import tkinter&#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;…

AVL树详解

目录 AVL树的概念 旋转的介绍 单旋转 双旋转 旋转演示 具体实现 通过高度判断的实现 通过平衡因子判断的实现 AVL树的概念 AVL树是一种自平衡的平衡二叉查找树&#xff0c;它是一种高效的数据结构&#xff0c;可以在插入和删除节点时保持树的平衡&#xff0c;从而保证…

vivado时序分析-1

AMD Vivado ™ 集成设计环境 (IDE) 提供了多项报告命令 &#xff0c; 用于验证设计是否满足所有时序约束 &#xff0c; 以及是否准备好加载到应用开发板上。“Report Timing Summary ” &#xff08; 时序汇总报告 &#xff09; 属于时序验收报告 &#xff0c; 等同于 ISE De…

uniapp中picker 获取时间组件如何把年月日改成年月日默认时分秒为00:00:00

如图所示&#xff0c;uniapp中picker组件的日期格式为&#xff1a; 但后端要 2023-11-08 00:00:00格式 如何从2023-11-08转化为 2023-11-08 00:00:00&#xff1a;&#x1f447; const date new Date(e.detail.value);//"2023-11-17" date.setHours(0, 0, 0); // 2…

springboot actuator:开放全部(部分)端点、端点映射、端点保护

目录 开放全部端点&#xff08;不安全&#xff09;&#xff1a; 开放部分端点 端点映射 端口保护 1、 添加Spring Security依赖&#xff1a; 2、Spring Security简单配置类&#xff1a; 3、application.yml配置规则 4、写一个简单的controller 5、简单登录页面 目…

【hcie-cloud】【2】华为云Stack解决方案介绍、缩略语整理 【下】

文章目录 华为文档获取方式、云计算发展背景、坚实基座华为云Stack&#xff0c;政企只能升级首选智能数据湖仓一体&#xff0c;让业务洞见更准&#xff0c;价值兑现更快MRS&#xff1a;一个架构可构建三种数据湖&#xff0c;业务场景更丰富离线数据湖&#xff1a;提供云原生、湖…

强化您的应用安全,从app加固开始

强化您的应用安全&#xff0c;从app加固开始 目录 强化您的应用安全&#xff0c;从app加固开始 摘要 引言 1. 加密和数据保护 2. 代码混淆 3. 防止反编译 4. 安全测试 5. 更新和补丁 6. 权限控制 7. 输入验证和输出过滤 8. 日志记录和监控 9. 安全设计和架构 10.…

GoLong的学习之路(二十二)进阶,语法之并发(go最重要的特点)(channel的主要用法)

这一章是接上一章内容继续&#xff0c;上一章说到协程也就是goroutine&#xff0c;如何使用它&#xff0c;这一张是讲一种数据结构。当然这个章节的数据结构非常重要。可以说这个数据结构就是为了方便协程&#xff0c;才制作出来的。 单纯地将函数并发执行是没有意义的。函数与…

echart宽度100px原因(解决el-tabs里的echarts图表宽度不自适应,只有100px问题)

目录 问题描述产生原因处理方法1.使用echart 的API —— resize()2.使用 v-if 总结 问题描述 项目中在el-tabs下面使用了图表&#xff0c;发现图表的宽度始终只有100px 产生原因 首先echart初始化的组件宽度设置了width: 100%&#xff0c;那么本来这个时候&#xff0c;echar…

Flutter android和ios闪屏页配置

一.概念理解 闪屏页 1.当点击app开始的一瞬间&#xff0c;所呈现出来的页面就是闪屏页。 2.为什么会有闪屏也&#xff0c;由于app启动需要加载代码&#xff0c;这个过程需要耗时&#xff0c;在没有加载完成之前&#xff0c;是看不到app真正的页面。所以app在没有完全加载完时…

计算摄像技术03 - 数字感光器件

一些计算摄像技术知识内容的整理&#xff1a;感光器件的发展过程、数字感光器件结构、数字感光器件的指标。 目录 一、感光器件的发展过程 二、数字感光器件结构 &#xff08;1&#xff09;CCD结构 ① 微透镜 ② 滤光片 ③ 感光层 电荷传输模式 &#xff08;2&#xff09;CMOS结…

nigix安装以及遇到的问题

Nginx配置 nginx双击闪退如何解决 修改配置文件 端口冲突&#xff0c;将端口改为90 Nginx 动静分离&#xff08;前端的代码单独运行&#xff09; 将html文件夹里面的东西放到nginx里面的HTMl文件夹里面 负载均衡&#xff08;轮询&#xff0c;权重&#xff0c;哈希&#xff…

三数之和(双指针)

15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三…

企业如何落地搭建商业智能BI系统

随着新一代信息化、数字化技术的应用&#xff0c;引发了新一轮的科技革命&#xff0c;现代化社会和数字化的联系越来越紧密&#xff0c;数据也变成继土地、劳动力、资本、技术之后的第五大生产要素&#xff0c;这一切都表明世界已经找准未来方向&#xff0c;前沿科技也与落地并…

数据库 高阶语句

目录 数据库 高阶语句 使用select 语句&#xff0c;用order by来对进行排序 区间判断查询和去重查询 如何对结果进行分组查询group by语句 limit 限制输出的结果记录&#xff0c;查看表中的指定行 通配符 设置别名&#xff1a;alias 简写就是 as 使用select 语句&#x…

CVE-2023-0179-Nftables整型溢出

前言 Netfilter是一个用于Linux操作系统的网络数据包过滤框架&#xff0c;它提供了一种灵活的方式来管理网络数据包的流动。Netfilter允许系统管理员和开发人员控制数据包在Linux内核中的处理方式&#xff0c;以实现网络安全、网络地址转换&#xff08;Network Address Transl…

19、Flink 的Table API 和 SQL 中的自定义函数及示例(3)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

2023年破圈:盘点11个新零售商业模式,永远不再打商业价格战

2023年破圈&#xff1a;盘点11个新零售商业模式&#xff0c;永远不再打商业价格战 前沿&#xff1a;纵观今年互联网各种类型项目&#xff0c;基本都是又短又快&#xff0c;但依然也有风靡的短跑冠军&#xff0c;那么互联网的项目能否跑的长久&#xff0c;是否是商业模式的原因&…

C++ —— map 和 multimap

一、map 1.介绍 1. map是关联容器&#xff0c;它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。 2. 在map中&#xff0c;键值key通常用于排序和惟一地标识元素&#xff0c;而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同&am…

NAT协议

目录 NAT 前言 NAT地址转换表 NAT分类 前言 静态NAT 192.168.1.2访问200.1.1.2执行过程 动态NAT 192.168.1.2访问200.1.1.2执行过程 NAPT 192.168.1.2的5000端口访问200.1.1.2的80端口执行过程 基本命令 配置动态NAPT转换 定义内外网接口 配置NAPT 静态NAPT配置…