前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >动态规划最长公共子序列(LCS)问题(Java实现)

动态规划最长公共子序列(LCS)问题(Java实现)

原创
作者头像
ruochen
修改于 2021-05-14 06:43:45
修改于 2021-05-14 06:43:45
1.4K0
举报

动态规划最长公共子序列(LCS)问题(Java实现)

首先,明白一个公共子序列和公共子串的区别

公共子序列: 可以不连续

公共子串: 必须连续

问题分析


  1. 求最长公共子序列,先明白两个概念
    • 子序列 - 一个给定序列中删去若干元素后得到的序列
    • 公共子序列 - 给定两个序列X,Y,当另一序列Z 既是X 的子序列,又是Y 的子序列时,就称Z 为X、Y 的公共子序列
  2. 明白上述两个概念后,我们就可以开始搜索最长公共子序列
    • 这个问题可以使用暴力方法解决,但是由于要全部搜索一遍,时间复杂度为 O(n2<sup>m</sup>),所以我们不采用
    • 我们可以使用动态规划算法,自底向上进行搜索,这样,在计算后面的时候,前面的数据我们已经对其进行保存,直接进行计算即可,时间复杂度很大程度降低。
  3. 既然决定使用动态规划算法,首先引入一个二位数组 c, 记录 xi 与 yj 的LCS 的长度,bi 记录 ci 的通过哪一个子问题的值求得的,以决定搜索方向。
  4. 抽取状态转移方程(X=x<sub>1</sub>x<sub>2</sub>...x<sub>m</sub>、Y=y<sub>1</sub>y<sub>2</sub>...y<sub>n</sub>为两个序列,Z=z<sub>1</sub>z<sub>2</sub>...z<sub>k</sub>为公共子序列)
    • 对于 xi 和 yj, 若 i = 0 or j = 0,显然,ci = 0
    • 若 i = j,我们可以使用上一步计算的值直接进行计算,即 ci = ci-1 + 1
    • 若 i ≠ j,有两种情况 1. Z<sub>k</sub> ≠ X<sub>m</sub>,那么Z 一定是X<sub>m-1</sub>, Y 的一个公共子序列, 2. Z<sub>k</sub> ≠ Y<sub>n</sub>,那么Z 一定是X, Y<sub>n-1</sub> 的一个公共子序列
    • 这样,第三种情况我们就可以表示成: ci = max{ci-1, ci}
    • 那么,我们就可以写出其状态转移方程

$$ci = \begin{cases}

0 & i = 0,or, j = 0 \

ci-1 + 1 & xi = yj \

max{ci-1, ci} & xi ≠ yj

\end{cases}$$

Java代码实现

代码语言:txt
AI代码解释
复制
/*
 * 若尘
 */
package lsc;

/**
 * 最长公共子序列 
 * @author ruochen
 * @version 1.0
 */
public class LSCProblem {
	
		/** lcs 用来保存最优解 */
		private static String lcs = "";

	public static void main(String[] args) {
		String str1 = "ABCDBC";
		String str2 = "ABCEAC";
		
		String[] x = strToArray(str1);
		String[] y = strToArray(str2);
		
		int[][] b = getSearchRoad(x, y);
		
		Display(b, x, x.length - 1, y.length - 1);
		System.out.println("lcs: " + lcs);
		System.out.println("len: " + lcs.length());
	}
	
	
	/**
	 * 
	 * @param str
	 * @return
	 */
	public static String[] strToArray(String str) {
		String[] strArray = new String[str.length() + 1];
		strArray[0] = "";
		for (int i = 1; i < strArray.length; i++) {
			strArray[i] = ""+str.charAt(i - 1);
		}
		return strArray;
	}
	
	/**
	 * 计算最长子序列长度以及记录最优解数组
	 * @param x 序列1
	 * @param y 序列2
	 * @return 返回一个可查询最优解的数组
	 */
	public static int[][] getSearchRoad(String[] x, String[] y) {
		int[][] b = new int[x.length][y.length];
		int[][] c = new int[x.length][y.length];
		
		// 第一行 or 第一列,x[i] or y[j] 为0, 对应 c[i][j] 赋值为0 
		for (int i = 0; i < x.length; i++) {
			c[i][0] = 0;
		}
		for (int j = 0; j < y.length; j++) {
			c[0][j] = 0;
		}
		for (int i = 1; i < x.length; i++) {
			for (int j = 1; j < y.length; j++) {
				if (x[i].equals(y[j])) {
					c[i][j] = c[i-1][j-1] + 1;
					// b[i][j] = 1 表示取决于左上方
					b[i][j] = 1;
				} else if (c[i-1][j] >= c[i][j-1]) {
					// 此处因为还要记录b[i][j],所以没有使用max函数
					c[i][j-1] = c[i-1][j];
					// b[i][j] = 0 表示取决于左边
					b[i][j] = 0;
				} else {
					c[i][j] = c[i][j-1];
					// b[i][j] = -1 表示取决于上边
					b[i][j] = -1;
				}
			}
		}
		return b;
	}
	
	/**
	 * 自右下向左上回溯,输出最优解
	 * @param b
	 * @param x
	 * @param i
	 * @param j
	 */
	public static void Display(int[][] b, String[] x, int i, int j) {
		if (i == 0 || j == 0) {
			return ;
		}
		if (b[i][j] == 1) {
			Display(b, x, i - 1, j - 1);
			lcs += x[i];
		} else if (b[i][j] == 0) {
			Display(b, x, i - 1, j);
		} else if (b[i][j] == -1) {
			Display(b, x, i, j - 1);
		}
	}
	
	/**
	 * 返回两个数的较大值
	 * @param x 第一个数
	 * @param y 第二个数
	 * @return
	 */
	/*
	public static int max(int x, int y) {
		return (x >= y) ? x : y; 
	}
	*/
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
面试题:非对称加密和对称加密的区别以及优缺点
在计算机安全领域,加密是一种常用的手段来保护数据的安全性。对称加密和非对称加密是两种常见的加密方式,它们在Java中都有相应的实现。
GeekLiHua
2025/01/21
1430
java之jce「建议收藏」
Java Cryptography Extension(JCE)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
全栈程序员站长
2022/07/05
2.5K0
SpringCloud-数据认证加密总结
在当今分布式系统的日益复杂和信息传递的广泛网络化环境中,确保通信的安全性至关重要。数据的加密和认证作为保障信息传递安全的关键手段,在分布式系统中扮演着不可或缺的角色。Spring Cloud,作为一套构建微服务架构的强大框架,提供了多种灵活而强大的数据加密和认证方式。从传统的 MD5 散列算法到现代的 OAuth 2.0 和 JWT(JSON Web Token)标准,每种加密和认证方式都针对不同的应用场景和安全需求提供了特定的解决方案。
Damon小智
2024/03/06
2160
SpringCloud-数据认证加密总结
Java安全之安全加密算法
本篇文来谈谈关于常见的一些加密算法,其实在此之前,对算法的了解并不是太多。了解的层次只是基于加密算法的一些应用上。也来浅谈一下加密算法在安全领域中的作用。写本篇文也是基于算法的应用和实现,也是我的基本原则,能用就行。
全栈程序员站长
2021/04/07
1.4K0
Java安全之安全加密算法
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
随着信息安全的日益重要,加密技术在软件开发领域中扮演着关键的角色。Java作为一门广泛应用的编程语言,提供了丰富的加密库和API,使得开发者可以轻松实现各种加密算法。本文将深入探索Java技术中常用到的六种加密技术,包括对称加密、非对称加密、哈希算法、消息摘要、数字签名和数字证书,并通过具体的实现代码帮助读者更好地理解和应用这些加密技术。
IT_陈寒
2024/01/08
3170
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
关于加解密、加签验签的那些事 | 得物技术
面对MD5、SHA、DES、AES、RSA等等这些名词你是否有很多问号?这些名词都是什么?还有什么公钥加密、私钥解密、私钥加签、公钥验签。这些都什么鬼?或许在你日常工作没有听说过这些名词,但是一旦你要设计一个对外访问的接口,或者安全性要求高的系统,那么必然会接触到这些名词。所以加解密、加签验签对于一个合格的程序员来说是必须要掌握的一个概念。接下来我们就一文彻底搞懂这些概念。
用户10346649
2023/03/10
1K0
关于加解密、加签验签的那些事 | 得物技术
支付项目中常用的加密解密算法一文讲透
作为支付机构,传输的数据大多是非常隐私的,比如身份证号、银行卡号、银行卡密码等。一旦这些信息被不法分子截获,就可能直接被盗刷银行卡,给消费者造成巨大损失。如果不法分子获取的信息是加密的,且没有解密的秘钥,那么对于不法分子来说这些信息就是一堆乱码,这就是加码最重要的意义。
用户3587585
2024/04/30
1.2K0
支付项目中常用的加密解密算法一文讲透
面试官:如何设计一个对外的安全接口?
哈喽,我是狗哥。最近在跟业务方对接需要我这边出个接口给到他们调用,这种涉及外部调用的接口设计,一般都涉及很多方面,比如:
JavaFish
2022/01/17
5850
面试官:如何设计一个对外的安全接口?
[Java 安全]加密算法
Base64编码 算法简述 定义 Base64内容传送编码是一种以任意8位字节序列组合的描述形式,这种形式不易被人直接识别。 Base64是一种很常见的编码规范,其作用是将二进制序列转换为人类可读的A
静默虚空
2018/01/05
3.9K0
[Java 安全]加密算法
对称加密与非对称加密
优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。
lyb-geek
2022/03/09
2.5K0
加密与安全_探索非对称加密算法_RSA算法
加密与安全_探索密钥交换算法(Diffie-Hellman算法) 中我们可以看到,公钥-私钥组成的密钥对是非常有用的加密方式,因为公钥是可以公开的,而私钥是完全保密的,由此奠定了非对称加密的基础。
小小工匠
2024/05/26
1950
每日一博 - 对称加密算法 vs 非对称加密算法
我们今天来梳理一下将分别介绍这两种加密算法的优缺点,并通过Java代码实现和测试结果来验证其效果。
小小工匠
2023/05/29
4770
加密-解密详解
参考视频: https://www.bilibili.com/video/BV1tz4y197hm
用户5927264
2020/07/30
2.8K0
SpringBoot 实现 RAS+AES 自动接口解密
目前常用的加密方式就对称性加密和非对称性加密,加密解密的操作的肯定是大家知道的,最重要的使用什么加密解密方式,制定什么样的加密策略;考虑到我技术水平和接口的速度,采用的是RAS非对称加密和AES对称加密一起用!!!!
程序员蜗牛
2024/05/10
1620
SpringBoot 实现 RAS+AES 自动接口解密
JAVA中的加密算法之双向加密(二)
本节主要讲述Java双向加密算法中的非对称加密算法实现。 (二)、非对称加密 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
幽鸿
2020/04/02
1.6K0
JAVA使用几种非对称加密
DH: package com.fengyunhe.asymmetric; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.*; import java.security
前Thoughtworks-杨焱
2021/12/08
4510
如何使用Java进行加密和解密
在Java中,我们可以使用许多不同的加密和解密技术来保护数据。这些技术可以用于加密密码、保护敏感数据、网络通信等。下面将介绍Java中常用的加密和解密技术和实现方法。
用户1289394
2023/09/22
7190
如何使用Java进行加密和解密
哈希算法是对称算法还是非对称算法_对称加密和非对称加密原理
作用:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。 哈希算法的目的:为了验证原始数据是否被篡改。 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。
全栈程序员站长
2022/11/01
1.2K0
Java中的加密和解密是什么,提供一个使用加密和解密的实际案例
在Java中,加密和解密是信息安全领域中非常重要的概念,它们用于保护数据的机密性和完整性。加密是指将明文转换为密文的过程,而解密则是将密文还原为明文的过程。在实际应用中,我们通常使用一些加密算法来对数据进行加密,以保护数据的安全性。
用户1289394
2024/05/29
1940
Java中的加密和解密是什么,提供一个使用加密和解密的实际案例
深入解析ECC(椭圆曲线密码学)加解密算法
随着互联网的普及和信息安全需求的不断提高,密码学在保护数据安全方面发挥着越来越重要的作用。公钥密码体制作为一种常见的加密方式,为数据安全提供了可靠的保障。ECC(椭圆曲线密码学)是一种新型的公钥密码体制,相比传统的RSA算法,在相同安全性要求下,ECC所需的密钥长度更短,运算效率更高,因此在现代密码学领域得到了广泛应用。
公众号:码到三十五
2024/05/24
1.4K0
深入解析ECC(椭圆曲线密码学)加解密算法
推荐阅读
相关推荐
面试题:非对称加密和对称加密的区别以及优缺点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档