当前位置: 首页 > news >正文

python 回溯法 子集树模板 系列 —— 14、最长公共子序列(LCS)

问题

输入

第1行:字符串A
第2行:字符串B
(A,B的长度 <= 1000)

输出

输出最长的子序列,如果有多个,随意输出1个。

输入示例

belong
cnblogs

输出示例

blog

分析

既然打算套用回溯法子集树模板,那就要祭出元素-状态空间分析大法。

以长度较小的字符串中的字符作为元素,以长度较大的字符串中的字符作为状态空间,对每一个元素,遍历它的状态空间,其它的事情交给剪枝函数!!!

解x的长度不固定,xi表示字符串b中的序号。

在处理每一个元素时,如果没有一个状态被选择(cnblogs中没一个字符被选取),那么程序无法去往下一个元素

这确实是个不小的麻烦!!!思考了一天,终于想出办法了:扩充状态空间,增加一个状态q!如果元素选取了状态q,它是合法的。但是,状态q不加入解x内!!!

看一个直观的图:
img_25da8190f7c844624700a3b037ec2cde.jpg

至此,enjoy it!

代码


'''最长公共子序列'''

# 作者:hhh5460
# 时间:2017年6月3日

a = 'belong'
b = 'cnblogs'

x = []   # 一个解(长度不固定)xi是b中字符的序号
X = []   # 一组解

best_x = [] # 最佳解
best_len = 0 # 最大子序列长度


# 冲突检测
def conflict(k):
    global n, x, X, a,b,best_len
    
    # 如果两个字符不相等
    if x[-1] < len(b) and a[k] != b[x[-1]]:
        return True
        
    # 如果两个字符相等,但是相对于前一个在b中的位置靠前
    if a[k] == b[x[-1]] and (len(x) >= 2 and x[-1] <= x[-2]):
        return True
        
    # 如果部分解的长度加上后面a剩下的长度,小于等于best_len
    if len(x) + (len(a)-k) < best_len:
        return True
    
    return False # 无冲突

    
# 回溯法(递归版本)
def LCS(k): # 到达a中的第k个元素
    global x, X,a,b,best_len,best_x
    #print(k, x)
    if k == len(a):  # 超出最尾的元素
        if len(x) > best_len:
            best_len = len(x)
            best_x = x[:]
    else:
        for i in range(len(b)+1): # 遍历 状态空间:0~len(b)-1,技巧:人为增加一种状态len(b),表示改行没有元素选取
            if i==len(b): # 此状态不放入解x内
                LCS(k+1)
            else:
                x.append(i)
                if not conflict(k): # 剪枝
                    LCS(k+1)
                x.pop()              # 回溯


# 根据一个解x,构造最长子序列lcs
def get_lcs(x):
    global b
    
    return ''.join([b[i] for i in x])

# 测试
LCS(0)
print(b)
print(best_x)
print(get_lcs(best_x))

效果图

img_2f0223e1d251923d1e210f951a9fa7ac.jpg

相关文章:

  • 开源中国 2013 大记事
  • 理解Scala的Symbol类型
  • Centos7修改主机名
  • MySQL改变表的存储引擎
  • 30 个 PHP 的 Excel 处理类
  • Factory Method模式 (一)
  • Androidn Notification的使用,解决找不到setLatestEventInfo方法
  • Mesos 框架的测试平台 minimesos
  • easyui的datagird动态设置当前页数
  • Spring-MVC
  • Irrlicht 3D Engine 笔记系列 之 教程6- 2D Graphics
  • 支撑起整个互联网时代的 7 款开源软件
  • 【Windows 10 应用开发】如何防止应用程序被截屏
  • gradle.org
  • c# 可空类型
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • EventListener原理
  • javascript 哈希表
  • leetcode46 Permutation 排列组合
  • Promise面试题,控制异步流程
  • SQLServer插入数据
  • 大快搜索数据爬虫技术实例安装教学篇
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 跳前端坑前,先看看这个!!
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • 最简单的无缝轮播
  • ionic入门之数据绑定显示-1
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)认识微服务
  • (转)http-server应用
  • (转)setTimeout 和 setInterval 的区别
  • ***监测系统的构建(chkrootkit )
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .Net Winform开发笔记(一)
  • .net开发时的诡异问题,button的onclick事件无效
  • @EnableWebMvc介绍和使用详细demo
  • @ResponseBody
  • [ Linux ] Linux信号概述 信号的产生
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BROADCASTING]tensor的扩散机制
  • [CareerCup] 14.5 Object Reflection 对象反射
  • [Cocoa]iOS 开发者账户,联机调试,发布应用事宜
  • [flink总结]什么是flink背压 ,有什么危害? 如何解决flink背压?flink如何保证端到端一致性?
  • [HTML]Web前端开发技术28(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [Java基础] Java中List.remove报错UnsupportedOperationException
  • [java基础揉碎]方法的重写/覆盖
  • [Linux](16)网络编程:网络概述,网络基本原理,套接字,UDP,TCP,并发服务器编程,守护(精灵)进程
  • [Machine Learning][Part 8]神经网络的学习训练过程
  • [nlp] 多语言大模型不同语种/语系数据的数据配比调节
  • [P7885][Android13] 解决5G信号良好状态栏信号只有两格的问题