最长公共子序列(线性dp)-java

news2024/11/24 23:06:19

本文主要来描述两个字符串的最长公共子序列问题

文章目录

前言

一、最长公共子序列

二、算法思路

1.dp[i][j]的四种情况

2. dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]的关系

3.dp数组的状态转移方程

 4.dp数组具体如下

三、代码如下

1.代码如下(示例):

2.读入数据

3.代码运行结果

总结


前言

本文主要来描述两个字符串的最长公共子序列问题


提示:以下是本篇文章正文内容,下面案例可供参考

一、最长公共子序列

定两个长度分别为 N 和 M 的字符串 A 和 B,求既是 A 的子序列又是 B的子序列的字符串长度最长是多少。

二、算法思路

1.dp[i][j]的四种情况

引入字符数组a和b,字符数组a存入字符串A,字符数组b存入字符串B。

我们引入二维数组dp,dp[i][j]表示的含义为表示所有在第一个字符串中出现的前i个字母即a[i]和第二个字符串中出现的前j个字母即b[j]的公共子序列。

图1.1思路模拟 

dp[i][j]通常是由以下4种情况构成

  • 当a[i]和b[j]都不取。即取字符串A前i -1个字符和字符串B的前j-1个字符的最长公共子序列的长度dp[i-1]dp[j-1]
  • 当a[i]不取,b[j]取。而dp[i-1][j]表示的是字符串A的前i-1个字符和字符串B的前j个字符的最长公共子序列,其中可能包括字符串B的第j个字符也可能不包括字符串B的第j个字符。
  • 当a[i]取,b[j]不取。dp[i][j-1]表示的字符串A的前i个字符和字符串B的前j-1的字符的最长公共子序列,其中可能包括字符串A的第i个字符也可能不包括字符串A的第i个字符。
  • 当a[i]和b[j]都取,即字符串A的第i个字符和字符串B的第j个字符相等时,那么就代表我们取字符串A的前i-1个字符和字符串B的前j-1个字符的最长公共子序列的长度(即dp[i-1][j-1])加上1,既可以得到此时dp[i][j]的值,即dp[i][j] = dp[i-1]dp[j-1]+1

2. dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]的关系

图2.1dp[i-1][j]、dp[i][j-1]和dp[i-1][j-1]的关系 

dp[i-1][j]表示 字符串A的前i-1个字符和字符串B的前j个字符的最长公共子序列。

dp[i][j-1]表示的字符串A的前i个字符和字符串B的前j-1的字符的最长公共子序列

那么dp[i-1][j]和dp[i][j-1]的重复的部分就表示字符串A的前i-1个字符和字符串B的前j-1个字符串的最长公共子序列即dp[i-1][j-1]。(不取字符串A的第i个字符和字符串B的第j个字符)

3.dp数组的状态转移方程

因为我们dp[i][j]表示的值是上述所描述的4种情况取最大值,那么我们就不必再取dp[i-1][j-1]的值,因为dp[i-1][j]的值和dp[i][j-1]的值肯定都比dp[i-1][j-1]的值大,dp[i-1][j-1]分别是dp[i-1][j]和dp[i][j-1]的子集。

当a[i] != b[j]时:

dp[i][j] = max(dp[i-1][j],dp[i][j-1])

当a[i] = b[j]时:

dp[i][j] =max(dp[i][j], dp[i-1][j-1]+1)

 4.dp数组具体如下

我们以测试样例字符串acbd和字符串abedc为例,dp数组各个值如下:

0 0 0 0 0 0 
0 1 1 1 1 1 
0 1 1 1 1 2 
0 1 2 2 2 2 
0 1 2 2 3 3

三、代码如下

1.代码如下(示例):


import java.io.*;
import java.util.Scanner;

public class 最长公共子序列 {
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public static void main(String[] args) throws Exception{
        Scanner sc =new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        int n = sc.nextInt();
        int m = sc.nextInt();
        String a = sc.next();
        String b = sc.next();
        char[] Achar = new char[1010];
        char[] Bchar = new char[1010];
        for(int i = 1;i <= n;i++){
            Achar[i] = a.charAt(i-1);
        }
        for(int i = 1;i <= m;i++){
            Bchar[i] = b.charAt(i-1);
        }
        int[][] dp = new int[1010][1010];
        for(int i = 1;i <= n;i++){
            for(int j = 1; j<= m;j++){
                dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
                if(Achar[i] == Bchar[j]){
                    dp[i][j] = Math.max(dp[i][j],dp[i-1][j-1]+1);
                }
            }
        }
        pw.println(dp[n][m]);
        pw.flush();
    }
    public static int nextInt()throws Exception{
        st.nextToken();
        return (int)st.nval;
    }
}

2.读入数据

4 5
acbd
abedc

3.代码运行结果

3

即acbd和abedc的最长公共子序列为abd,长度为3 


总结

只要弄懂dp[i][j]、dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]各个值之间的关系和状态转移方程的由来即可解决最长公共子序列问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux shell编程学习笔记46:awk命令的由来、功能、格式、选项说明、版权、版本

0 前言 在编写Linux Shell脚本的过程中&#xff0c;我们经常要对Linux命令执行的结果进行分析和提取&#xff0c;Linux也在文本分析和提取这方面提供了不少的命令。比如我们之前研究过的cut命令。 Linux shell编程学习笔记43&#xff1a;cut命令https://blog.csdn.net/Purple…

【LeetCode】手撕系列—82. 删除排序链表中的重复元素 II

目录 1- 思路2- 题解⭐删除排序链表中的重复元素 II——题解思路 3- ACM模式 原题链接&#xff1a;82. 删除排序链表中的重复元素 II 1- 思路 定义虚拟头结点 定义 cur 指针&#xff0c;cur指针始终指向虚拟头结点&#xff0c;依此操作 cur.next 和 cur.next.next while条件为…

无线游戏手柄的测试(Windows11系统手柄调试方法)

实物 1、把游戏手柄的无线接收器插入到电脑usb接口中 2、【控制面板】----【查看设备和打印机】 3、【蓝牙和其它设备】--【更多设备和打印机设置】 4、鼠标右键【游戏控制器设置】 5、【属性】 6、【测试】&#xff08;每个按键是否正常&#xff09; 7、【校准】&#xff08;…

微信自动回复这样设置,让你的沟通更加高效便捷!

面对繁忙的生活和不断涌入的信息&#xff0c;我们往往无法及时回复微信好友的消息&#xff0c;这给沟通带来了一定的困扰。有没有一种方法能够让我们在忙碌的同时&#xff0c;依然能够及时回复好友并提高沟通效率呢&#xff1f; 答案是肯定的&#xff01;我们可以通过微信管理…

智能传真机触摸屏中应用的触摸感应芯片

智能传真机是应用扫描和光电变换技术&#xff0c;把文件、图表、照片等静止图像转换成电信号&#xff0c;传送到接收端&#xff0c;以记录形式进行复制的通信设备。智能传真机将需发送的原件按照规定的顺序&#xff0c;通过光学扫描系统分解成许多微小单元&#xff08;称为像素…

配置交换机 SSH 管理和端口安全

实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握&#xff1a; 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 3、实验步骤 &#xff08;1&#xff09;配置交换机S1 Swit…

Linux:文本编辑器 - vim

Linux&#xff1a;文本编辑器 - vim vim基本操作普通模式模式切换移动光标复制粘贴删除替换撤销 底行模式行号查找 vim基本操作 Vim(Vi Improved)是一款功能强大的文本编辑器&#xff0c;是Unix/Linux系统中广泛使用的编辑器之一。它源于上世纪70年代开发的Vi编辑器&#xff0…

初识--数据结构

什么是数据结构&#xff1f;我们为什么要学习数据结构呢....一系列的问题就促使我们不得不了解数据结构。我们不禁要问了&#xff0c;学习C语言不就够了吗&#xff1f;为什么还要学习数据结构呢&#xff1f;这是因为&#xff1a;数据结构能够解决C语言解决不了的问题&#xff0…

数据结构和算法:回溯

回溯算法 回溯算法&#xff08;backtracking algorithm&#xff09;是一种通过穷举来解决问题的方法&#xff0c;它的核心思想是从一个初始状态出发&#xff0c;暴力搜索所有可能的解决方案&#xff0c;当遇到正确的解则将其记录&#xff0c;直到找到解或者尝试了所有可能的选…

spring-cloud微服务openfeign

Spring Cloud openfeign对Feign进行了增强&#xff0c;使其支持Spring MVC注解&#xff0c;另外还整合了Ribbon和Nacos&#xff0c;从而使得Feign的使用更加方便 优势&#xff0c;openfeign可以做到使用HTTP请求远程服务时就像洞用本地方法一样的体验&#xff0c;开发者完全感…

unity学习(83)——细节名称和血条

眼中有细节&#xff0c;学习的过程才能平稳&#xff01; 1.游戏更新时把名字也更新 代码如下&#xff1a; 效果如下&#xff1a; 2.因为是第三人称&#xff0c;从背后看&#xff0c;所以名称应该水平对称&#xff0c;翻转一下&#xff01;rotate y180 游戏内效果如下&#xf…

IEC101、IEC103、IEC104、Modbus报文解析工具

一、概述 国际电工委员会第57技术委员会&#xff08;IEC TC57&#xff09;1995年出版IEC 60870-5-101后&#xff0c;得到了广泛的应用。为适应网络传输&#xff0c;2000年IEC TC57又出版了IEC 60870-5-104&#xff1a;2000《远东设备及系统 第5-104部分&#xff1a;传输规约-采…

【数据交换格式】网络socket编程温度采集智能存储与上报项目技术------JSON、TLV

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

数据结构__顺序表和单链表

顺序表的改进 问题&#xff1a; 1. 中间/头部的插入删除&#xff0c;时间复杂度为O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不小的消耗。 3. 增容一般是呈2倍的增长&#xff0c;势必会有一定的空间浪费。例如当前容量为100&#xff0c;满了…

安卓逆向 | 某X游戏垂类Web nonce

*本案例仅做分析参考,如有侵权请联系删除 1.逻辑分析 通过XHR断点,然后逐步往上调发现nonce生出处。 在console执行下函数 其中 i,是当前日期和时间的秒级时间戳,并将其向下取整到最接近的整数。 i = ~~(+_.w() / 1e3)w</

CLI举例:上下行连接路由器(路由引流)

CLI举例&#xff1a;上下行连接路由器&#xff08;路由引流&#xff09; 介绍了集群设备&#xff0c;上下行连接路由器的配置举例。 组网需求 如图1所示&#xff0c;上行网络使用BGP&#xff0c;下行网络使用OSPF&#xff0c;多数据中心统一通过路由器R4接入Internet。 希望…

C++位图和布隆过滤器(含哈希切割)

文章目录 C位图和布隆过滤器&#xff08;含哈希切割&#xff09;1、位图&#xff08;Bitmap&#xff09;1.1、位图的概念1.2、位图的使用1.3、位图的模拟实现1.4、位图相关面试题 2、布隆过滤器&#xff08;Bloom Filter&#xff09;2.1、布隆过滤器的概念2.2、布隆过滤器的插入…

【通信原理笔记】【三】模拟信号调制——3.5 角度调制(FM、PM)与其频谱特性

文章目录 前言一、相位与频率二、PM和FM的数学表示三、FM的频谱四、FM信号的带宽——卡松公式总结 前言 在之前介绍的几种调制方式中&#xff0c;我提到信噪比时计算的是用户解调后的信噪比&#xff0c;然而在北邮通信原理课中考虑的是解调器输入的信噪比&#xff0c;即考虑的…

一键破解WB多条带--Swissprot数据库

WB条带不符合预期&#xff1f; 不要着急扔掉结果&#xff0c;有可能是重要信息忽略了哟&#xff01;Swissprot带你了解蛋白大小的前因后果。 UniProtKB/Swiss-Prot (reviewed) 是一个高质量人工注释且非冗余的蛋白序列数据库。其中包含各类实验结果、计算得到的特征信息和文献…

损失函数-交叉熵 梯度下降

文章目录 1、交叉熵的简单例子1.2、Classification Error&#xff08;分类错误率&#xff09;1.3、Mean Squared Error (均方误差)1.4、交叉熵损失函数1.5、二分类 2、什么是梯度下降法&#xff1f;2.2、梯度下降法的运行过程2.3、二元函数的梯度下降 1、交叉熵的简单例子 参考…