【动态规划】最长公共子序列和最长公共子串(python)

2023-11-15

编写用时:2020年3月12日12:02:28~1h
动态规划经典例题——最长公共子序列和最长公共子串(python)
很久之前大概是高中的时候写过这种题目,使用动态规划的方法求解的,现读研究生了,要把过去的拾起来的呢。

1. 最长公共子序列(LCS)

1.1 问题描述

在这里插入图片描述

1.2 思路

利用动态规划。
在这里插入图片描述
下一步就要找到状态之间的转换方程。
在这里插入图片描述
因此可以根据这个方程来进行填表,以"helloworld"和“loop”为例:
在这里插入图片描述

1.3 Python代码

def LCS(string1,string2):
    len1 = len(string1)
    len2 = len(string2)
    res = [[0 for i in range(len1+1)] for j in range(len2+1)] 
     #python 初始化二维数组 [len2+1],[len1+1]
    for i in range(1,len2+1):  #开始从1开始,到len2+1结束
        for j in range(1,len1+1):  #开始从1开始,到len2+1结束
            if string2[i-1] == string1[j-1]:
                res[i][j] = res[i-1][j-1]+1
            else:
                res[i][j] = max(res[i-1][j],res[i][j-1])
    return res,res[-1][-1]  #返回res[len2+1][len1+1]
print(LCS("helloworld","loop"))
# 输出结果为:
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
 [0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2],
 [0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3],
 [0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3]], 3

所以"helloworld"和"loop"的最长公共子序列的长度为3。

1.4 找到具体的子序列

下面的内容借鉴了博主Running07的博客动态规划 最长公共子序列 过程图解
如果有两个字符串如下:
S1 = “123456778”
S2 = “357486782”
其最终的动态规划填表结果为:
在这里插入图片描述
其中S1和S2的LCS并不是只有1个。
我们根据递归公式:

构建了上表,
通过递推公式,可以看出,res[i][j]的值来源于res[i-1][j]或者是res[i-1][j]和res[i][j-1]的较大值(可能相等)。
我们将从最后一个元素c[8][9]倒推出S1和S2的LCS。
res[8][9] = 5,且S1[8] != S2[9],所以倒推回去,res[8][9]的值来源于c[8][8]的值(因为res[8][8] > res[7][9])。
res[8][8] = 5, 且S1[8] = S2[8], 所以倒推回去,res[8][8]的值来源于 res[7][7]。
以此类推,如果遇到S1[i] != S2[j] ,且res[i-1][j] = res[i][j-1] 这种存在分支的情况,这里都选择一个方向(之后遇到这样的情况,也选择相同的方向,要么都往左,要么都往上)。
在这里插入图片描述

可得S1和S2的LCS为{3、5、7、7、8} 这是遇见相等的时候,统一往左走
S1和S2之间还有一个LCS 这是遇见相等的时候,统一往上走:
在这里插入图片描述
可得S1和S2的LCS为{3、4、6、7、8}

def LCS(string1,string2):
    len1 = len(string1)
    len2 = len(string2)
    res = [[0 for i in range(len1+1)] for j in range(len2+1)]  #python 初始化二维数组 [len1+1],[len2+1]
    for i in range(1,len2+1):  #开始从1开始,到len2+1结束
        for j in range(1,len1+1):  #开始从1开始,到len2+1结束
            if string2[i-1] == string1[j-1]:
                res[i][j] = res[i-1][j-1]+1
            else:
                res[i][j] = max(res[i-1][j],res[i][j-1])
    string=""  
    i=len(string2);
    j=len(string1);
    while (i > 0) & (j > 0):  #一开始我不知道加()逻辑错误
        #开始从1开始,到len2+1结束
        print(i,j)
        if string2[i-1] == string1[j-1]:
            string=string+string2[i-1]
            i=i-1
            j=j-1
        else:
            if res[i-1][j]>res[i][j-1]:
                i=i-1
            elif res[i-1][j]<res[i][j-1]:
                j=j-1
            else:
                i=i-1
    return res,res[-1][-1],string[::-1]  # 倒序输出
print(LCS("helloworld","loop"))

输出:
4 10
3 10
3 9
3 8
3 7
2 6
2 5
1 4
([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2], [0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3],
 [0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3]], 3, 'loo')

2. 最长公共子串

2.1 问题描述

在这里插入图片描述

2.2 思路

和最长公共子序列一样,使用动态规划的算法。
在这里插入图片描述
下一步就要找到状态之间的转换方程。
和LCS问题唯一不同的地方在于当A[i] != B[j]时,res[i][j]就直接等于0了,因为子串必须连续,且res[i][j] 表示的是以A[i],B[j]截尾的公共子串的长度。因此可以根据这个方程来进行填表,以"helloworld"和“loop”为例:
在这里插入图片描述
这个和LCS问题还有一点不同的就是,需要设置一个result,每一步都更新得到最长公共子串的长度。

2.3 Python代码

def LCstring(string1,string2):
    len1 = len(string1)
    len2 = len(string2)
    res = [[0 for i in range(len1+1)] for j in range(len2+1)]
    result = 0
    for i in range(1,len2+1):
        for j in range(1,len1+1):
            if string2[i-1] == string1[j-1]:
                res[i][j] = res[i-1][j-1]+1
                result = max(result,res[i][j])  
    return result
print(LCstring("helloworld","loop"))
# 输出结果为:2

2.4 返回子串

def LCS(string1,string2):
    len1 = len(string1)
    len2 = len(string2)
    res = [[0 for i in range(len1+1)] for j in range(len2+1)]  #python 初始化二维数组 [len1+1],[len2+1]
    result =0
    index=0
    for i in range(1,len2+1):  #开始从1开始,到len2+1结束
        for j in range(1,len1+1):  #开始从1开始,到len2+1结束
            if string2[i-1] == string1[j-1]:
                res[i][j] = res[i-1][j-1]+1
                if result<res[i][j]:
                    index=i
                result = max(res[i][j],result)         
    string=string2[index-result:index] 
   
    return res,result,string  # 输出
print(LCS("hellooxworld","looxoxp"))

([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 3, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], 
4, 'loox')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【动态规划】最长公共子序列和最长公共子串(python) 的相关文章

  • Java并发编程实战——彻底理解volatile

    文章目录 volatile作用 volatile实现原理 volatile的happens before关系 volatile的内存语义 volatile重排序与JMM内存屏障 volatile的使用误区 volatile的适用场景 vol
  • 编程技术面试的五大要点

    文 何海涛 扎实的基础知识 高质量的代码 清晰的思路 优化代码的能力 优秀的综合能力是编程技术面试的五大要点 找工作一直是一个热门话题 要想找到心仪的工作 难免需要经过多轮面试 编程面试是程序员面试过程中最为重要的一个环节 如果能在编程面试
  • 面试准备:Spring/Spring MVC常见面试题汇总

    文章目录 1 Spring框架有什么优点 2 什么是AOP 3 实现AOP的方式 AOP织入的三种时期 Spring AOP是怎么实现的 4 JDK动态代理实现方式 5 PageHelper实现方式 6 什么是IoC 什么是DI 7 Spr
  • 面试准备:Mybatis常见面试题汇总

    文章目录 1 和 的区别是什么 2 当实体类中的属性名和表中的字段名不一样 怎么办 3 模糊查询like语句该怎么写 4 Mybatis 一对一 一对多的xml怎么写 5 Dao 接口的工作原理是什么 Dao 接口里的方法 参数不同时 方法
  • 面试总结:测试常见面试题汇总

    文章目录 理论 测试流程 各个测试阶段 单元测试 集成测试 系统测试区别 测试用例设计 什么是好的测试用例 方法 用户登录 实例 App测试和Web测试的区别 典型测试场景 聊天功能测试用例怎么设计 怎么测试微信朋友圈 TODO 怎么测试微
  • 零拷贝的实现原理

    文章目录 引入 DMA PageCache 零拷贝 mmap sendfile SG DMA 使用零拷贝技术的项目 引入 在Java架构直通车 Kafka介绍和高性能原因一节中 介绍了Kafka的Zero Copy技术 本文将深入探究一下Z
  • 面试准备:Java新特性详解

    文章目录 Java语言新特性 1 Lambda表达式和函数式接口 2 接口的默认方法和静态方法 3 方法引用 4 重复注解 5 更好的类型推断 6 拓宽注解的应用场景 Java编译器新特性 参数名称 JVM的新特性 更多资料 参考 java
  • 面试准备:Java常见面试题汇总(一)

    面试准备 Java常见面试题汇总 一 面试准备 Java常见面试题汇总 二 面试准备 Java常见面试题汇总 三 文章目录 1 面向对象的特点 特性有哪些 补充 Java的多态是编译时多态还是运行时多态 2 接口和抽象类的相同点和不同点 3
  • 面试题目总结(CNN)

    CNN权值共享是什么 局部感知 即网络部分连通 每个神经元只与上一层的部分神经元相连 只感知局部 而不是整幅图像 滑窗实现 可行性 局部像素关系紧密 较远像素相关性弱 因此只需要局部感知 在更高层将局部的信息综合起来就得到了全局的信息 权值
  • Java架构直通车——以JDBC为例谈双亲委派模型的破坏

    文章目录 引入 JDBC4 0之前 JDBC4 0之后 引入 java给数据库操作提供了一个Driver接口 public interface Driver Connection connect String url java util P
  • 面试准备:Java常见面试题汇总(二)

    面试准备 Java常见面试题汇总 一 面试准备 Java常见面试题汇总 二 面试准备 Java常见面试题汇总 三 文章目录 43 java 中的 Math round 1 5 等于多少 44 String str abc 与 String
  • 处理器对原子操作的实现

    文章目录 引入 单核 多核 引入 原子操作对于我们来说 是非常熟悉的概念 从用户角度 可以用原子操作来替换重量级的锁同步 从而提高程序性能 底层实现角度 原子操作可以用于构建各种更重量级的同步操作 比如锁或屏障之类的 对于原子操作的实现来说
  • Java架构直通车——Java基础面试考点清单

    文章目录 基础 J U C jvm虚拟机 数据结构 算法 Spring RPC通信框架 网络通信 MQ 缓存 Mybatis 其他技术 基础 强引用 弱引用 虚引用 软引用 final关键字的作用 方法 变量 类 泛型 泛型继承 泛型擦除
  • 从头开始学Java——JVM虚拟机八问

    文章目录 什么是Java虚拟机 为什么Java被称为 平台无关的编程语言 什么是JIT HotSpot怎么工作的 HotSpot虚拟机要使用解释器与编译器并存的架构 什么是编译时 运行时 编译 运行 编译时运行时问题归纳 反射 描述Java
  • 招银网络科技电话面试

    1 关于项目的负责内容 还是非常有必要熟悉应急 天基的基础传输模块的 基本面试中都会觉得只界面模块很单薄 应急 基础传输模块 无人机网络协议 速率控制模块 界面模块 天基 基础传输模块 MRUDP 界面模块 2 TCP长连接 问 如何在TC
  • 测开面经总结的经常考察的知识点

    一 算法相关 1 熟悉常见的排序算法 冒泡排序 插入排序 选择排序 归并排序 堆排序 快排 希尔排序 二 计算机网络相关 1 http协议 http 超文本传输协议 是一个在客户端和服务器端之间基于请求与响应模式的 无状态的 应用层的协议
  • 【动态规划】最长公共子序列和最长公共子串(python)

    编写用时 2020年3月12日12 02 28 1h 动态规划经典例题 最长公共子序列和最长公共子串 python 很久之前大概是高中的时候写过这种题目 使用动态规划的方法求解的 现读研究生了 要把过去的拾起来的呢 1 最长公共子序列 LC
  • 面试准备:MySQL建立索引的原则

    文章目录 建立索引 1 和in可以乱序 2 最左前缀匹配原则 3 尽量选择区分度高的列作为索引 4 索引列不能参与计算 5 尽量的扩展索引 不要新建索引 6 为经常需要排序 分组和联合操作的字段建立索引 7 为常作为查询条件的字段建立索引
  • C++实现String类

    C 实现String类 还没有完成 待继续 有以下注意的点 1 赋值操作符返回的是一个MyString 而重载的 返回的是一个MyString 其中的原因参看 effective c 主要是返回引用的时候 必须返回必须在此函数之前存在的引用
  • Linux内核内存管理算法Buddy和Slab

    文章目录 Buddy分配器 CMA Slab分配器 总结 Buddy分配器 假设这是一段连续的页框 阴影部分表示已经被使用的页框 现在需要申请一个连续的5个页框 这个时候 在这段内存上不能找到连续的5个空闲的页框 就会去另一段内存上去寻找5

随机推荐

  • Android-组件化开发

    一 优点 1 基础功能复用 节省开发时间 在项目初期框架搭建的时候 基础功能可直接搬移复用 日积月累 每个人 公司应该都会有一套自己的Base 2 业务拆分 便于分工 实现解耦 单独的业务模块抽取成一个独立的Module 不同人员在各自的模
  • Spring框架之IOC(控制反转)-----(Inversion of Control)

    Spring框架之IOC 控制反转 Inversion of Control 什么是IOC 用来完成 原来由程序员主动通过new来实例化对象的这个事情 转交给Spring来负责创建对象 控制反转中 控制是控制类的对象 反转是指将对象交给Sp
  • nodejs连接mongodb数据库,通过each对数据库数据进行遍历时报错及解决方案

    平常我们用nodejs连接好mongodb数据库后 用find 方法随数据库数据进行查找 然后遍历 进行数据解析 遍历时一般采用each 方法进行遍历 但是有时候可能由于数据库版本和nodejs版本问题 会遍历出错 故提供一下解决方案 如代
  • 关于 torch 的 device id 与真实 GPU id 的关系

    需要知道的几个点 cuda id 中的 id 并不一定是真实硬件的GPU id 而是运行时可用的 GPU id 从0开始计数 torch cuda device count 可查看运行时可用的 GPU 数量 torch cuda get d
  • 空参构造方法和有参构造方法的使用

    脑筋不动 看视频就会打瞌睡 把代码敲出来才会发现问题 重新回顾了构造方法 空参和有参构造都能够调用show getxx show方法只是为了显示属性值 getxxx 获取属性值 可以打印 可以赋值给其他变量 声明一个手机类 package
  • HTTP 协议

    目录 编辑一 HTTP 协议是什么 二 抓包工具的使用 三 HTTP 请求 1 认识 URL 2 认识方法 3 认识请求 报头 HOST Content Length 和 Content Type 编辑 User Agent Referer
  • ipython import pandas出错

    其实这个错误是早上就发现了的 但是由于代码上运行没得问题 我就纳闷了 但是可以运行代码就无伤大雅 下午事情差不多了 想起这个问题 就来debug一下 为了让错误更加清晰的呈现出来 我又要费大家电了 lt 哈哈 gt 下面就是报的完整错误 I
  • python 运行时出现fixture xxx not found

    一 问题 在pycharm中运行带有pytest包的代码会出现如下错误 E fixture a not found gt available fixtures cache capfd capfdbinary caplog capsys ca
  • Obsidian 常用插件记录+typora 转移过来问题记录

    Typora 转 Obsidian 一些常用插件记录 插件目录 一 插件 1 obsidian custom attachment location 2 obsidian editing toolbar 3 待续 二 问题 1 图片展示问题
  • 比较器

    Comparator比较器 Collcetion工具集中的sort public static
  • cc2530:<3>ADC采集光照度案例

    之前我们讲到了串口的收发数据 我们使用到了数据结构的环形对列 就是一个追赶模型 前面一个人在放数据 后面一个人在捡数据 定义两个变量来存储这两个人所走的步数 在定义一个库存变量 也就是用来表示前面一个人放数据的量减去后面一个人捡数据的量 我
  • 8086汇编指令查询小工具,JavaScript编写,浏览器直接运行

    程序界面 汇编语言还是在大学的时候学的 汇编语言有个特点是语句短 条数多 很难可以把全部指令都背熟 当时就想编写一个软件可以随时查阅汇编语言的各类指令 而且软件不需要编译可以随时更新 可惜当时用javascript语言写只写了一半 现在终于
  • JS逆向解析案例-巨潮证券市场数据库(python)

    目标网址 http webapi cninfo com cn marketDataZhishu 这篇文章是用来对该网站进行js解析用的 解析完后爬取数据操作可看这篇文章 Scrapy实战案例 将股票数据存入SQL数据库 解析重点 目标网址在
  • VS2017 Nuget找不到包的问题处理

    重新安装系统之后 发现新安装的VS2017在用Nuget搜索SDK时 一直提示找不到包 如下图 解决方法 1 点击右侧的设置按钮 2 弹出窗中左侧树形结构选择 程序包源 再点击右上方的添加按钮 输入以下信息 https api nuget
  • STM32H7串口IAP实现

    1 概述 通过IAP原理一文我们大概知道了IAP的工作原理和工作流程 但是现在要通过串口来将这个功能实现 我们应该怎么做呢 总体上整个代码可以分为4个部分 串口功能初始化 串口不定长数据接收 Flash写入以及IAP跳转 接下来我将一一解释
  • 图解通信原理与案例分析-22:4G LTE-A如何把速率提升到1G--多载波聚合技术与授权频谱辅助接入LAA

    TBD
  • druid监控的使用

    新建springboot项目 pom xml
  • RK3568平台开发系列:HX711调试 Android

    RK3568平台开发系列 HX711调试 Android 在本文中 我们将重点讲解如何在RK3568平台上调试HX711传感器 并将其与Android应用程序集成 我们将详细介绍HX711的工作原理 并提供相应的源代码示例 HX711是一款
  • C语言力扣第50题之Pow(x,n),求x的n次幂。递归算法

    50 Pow x n 实现 pow x n 即计算 x 的整数 n 次幂函数 即 xn 示例 1 输入 x 2 00000 n 10 输出 1024 00000 示例 2 输入 x 2 10000 n 3 输出 9 26100 示例 3 输
  • 【动态规划】最长公共子序列和最长公共子串(python)

    编写用时 2020年3月12日12 02 28 1h 动态规划经典例题 最长公共子序列和最长公共子串 python 很久之前大概是高中的时候写过这种题目 使用动态规划的方法求解的 现读研究生了 要把过去的拾起来的呢 1 最长公共子序列 LC