【算法进阶2-动态规划】最长公共子序列、欧几里得算法-分数、RSA算法-密码于加密

news/2024/9/13 11:39:35/ 标签: 算法, 动态规划, 代理模式

1 最长公共子序列
2 欧几里得算法
2.1 欧几里得算法-分数
3 RSA算法-密码于加密

1 最长公共子序列

在这里插入图片描述

-个序列的子序列是在该序列中删去若干元素后得 到的序列。
例:“ABCD”和“BDF”都是“ABCDEFG”的子序列最长公共子序列(LCS)问题:给定两个序列X和Y,求X和Y长度最大的公共子序列。
例:X="ABBCBDE" Y="DBBCDB" LCS(X,Y)="BBCD"应用场景:字符串相似度比对

在这里插入图片描述

from typing import Tupledef lcs_length(x: str, y: str) -> int:"""计算两个字符串的最长公共子序列 (LCS) 的长度。使用动态规划方法解决LCS问题。LCS问题是指在两个字符串中找到一个最长的子序列,使得这个子序列在两个字符串中都出现,并且保持其相对顺序不变。:param x: 第一个字符串:param y: 第二个字符串:return: 返回两个字符串的最长公共子序列的长度"""m = len(x)  # 第一个字符串的长度n = len(y)  # 第二个字符串的长度# 创建一个 (m+1) x (n+1) 的二维列表 c,用于存储子问题的解# c[i][j] 表示字符串 x 的前 i 个字符和字符串 y 的前 j 个字符的最长公共子序列的长度c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]# 填充二维列表 cfor i in range(1, m + 1):  # 遍历字符串 x 的每个字符for j in range(1, n + 1):  # 遍历字符串 y 的每个字符if x[i - 1] == y[j - 1]:  # 如果 x 的第 i 个字符等于 y 的第 j 个字符# 如果字符匹配,当前最长公共子序列的长度是左上角的值 + 1c[i][j] = c[i - 1][j - 1] + 1else:# 如果字符不匹配,取上方或左方的最大值c[i][j] = max(c[i - 1][j], c[i][j - 1])# 打印二维列表 c 的值(用于调试)for _ in c:print('列表的值是:', _)# 返回最长公共子序列的长度,即 c[m][n]return c[m][n]# print(lcs_length("ABCBDAB", "BDCABA"))  # 4# 列表的值是: [0, 0, 0, 0, 0, 0, 0]
# 列表的值是: [0, 0, 0, 0, 1, 1, 1]
# 列表的值是: [0, 1, 1, 1, 1, 2, 2]
# 列表的值是: [0, 1, 1, 2, 2, 2, 2]
# 列表的值是: [0, 1, 1, 2, 2, 3, 3]
# 列表的值是: [0, 1, 2, 2, 2, 3, 3]
# 列表的值是: [0, 1, 2, 2, 3, 3, 4]
# 列表的值是: [0, 1, 2, 2, 3, 4, 4]def lcs(x: str, y: str) -> Tuple[int, list]:"""计算两个字符串的最长公共子序列 (LCS) 的长度,并生成动态规划表。使用动态规划方法求解两个字符串的最长公共子序列问题,并返回长度以及记录方向的表,用于后续的LCS路径恢复。:param x: 第一个字符串:param y: 第二个字符串:return: 返回一个元组,包含两个元素:- LCS的长度- 动态规划表 b,其中 b[i][j] 表示到达位置 (i, j) 时的方向"""m = len(x)  # 第一个字符串的长度n = len(y)  # 第二个字符串的长度# 创建一个 (m+1) x (n+1) 的二维列表 c,用于存储子问题的解# c[i][j] 表示字符串 x 的前 i 个字符和字符串 y 的前 j 个字符的最长公共子序列的长度c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]# 创建一个 (m+1) x (n+1) 的二维列表 b,用于记录方向# b[i][j] 表示到达位置 (i, j) 时的方向# "←" 表示来自左上方(匹配),# "↑" 表示来自上方(不匹配,向上移动),# "↖" 表示来自左方(不匹配,向左移动)b = [['*' for _ in range(n + 1)] for _ in range(m + 1)]# 填充二维列表 c 和 bfor i in range(1, m + 1):for j in range(1, n + 1):if x[i - 1] == y[j - 1]:  # 如果 x 的第 i 个字符等于 y 的第 j 个字符# 如果字符匹配,当前最长公共子序列的长度是左上角的值 + 1c[i][j] = c[i - 1][j - 1] + 1b[i][j] = "←"  # 方向来自于左上方(匹配)elif c[i - 1][j] > c[i][j - 1]:  # 如果来自上方的值大于来自左方的值# 如果上方的值更大,选择上方的值c[i][j] = c[i - 1][j]b[i][j] = "↑"  # 方向来自于上方(不匹配,向上移动)else:# 如果左方的值更大或相等,选择左方的值c[i][j] = c[i][j - 1]b[i][j] = "↖"  # 方向来自于左方(不匹配,向左移动)# 返回最长公共子序列的长度和方向记录表return c[m][n], bc, b = lcs("ABCBDAB", "BDCABA")
for _ in b:print(_)# ['*', '*', '*', '*', '*', '*', '*']
# ['*', '↖', '↖', '↖', '←', '↖', '←']
# ['*', '←', '↖', '↖', '↖', '←', '↖']
# ['*', '↑', '↖', '←', '↖', '↖', '↖']
# ['*', '←', '↖', '↑', '↖', '←', '↖']
# ['*', '↑', '←', '↖', '↖', '↑', '↖']
# ['*', '↑', '↑', '↖', '←', '↖', '←']
# ['*', '←', '↑', '↖', '↑', '←', '↖']def lcs_traceback(x: str, y: str) -> str:"""根据动态规划表回溯,找出两个字符串的最长公共子序列 (LCS)。使用动态规划表 `b` 来回溯最长公共子序列的路径,并从结果表 `c` 中获取最长公共子序列的字符。最终返回最长公共子序列的字符串。:param x: 第一个字符串:param y: 第二个字符串:return: 返回两个字符串的最长公共子序列(LCS)的字符串表示"""# 调用 lcs 函数获取动态规划表 c 和方向记录表 bc, b = lcs(x, y)i = len(x)  # 初始化 i 为第一个字符串的长度j = len(y)  # 初始化 j 为第二个字符串的长度res = []  # 用于存储回溯得到的 LCS 字符# 根据方向记录表 b 从表的右下角开始回溯到左上角while i > 0 and j > 0:if b[i][j] == "←":# 如果方向来自于左上方(匹配),则当前字符是 LCS 的一部分res.append(x[i - 1])i -= 1  # 移动到前一个字符j -= 1  # 移动到前一个字符elif b[i][j] == "↑":# 如果方向来自于上方,则移动到上方的子问题i -= 1else:  # '↖'# 如果方向来自于左方,则移动到左方的子问题j -= 1# 由于回溯过程中字符是从 LCS 的末尾开始添加的,所以需要反转结果列表return "".join(res[::-1])print(lcs_traceback("ABCBDAB", "BDCABA"))  # BDAB

2 欧几里得算法

在这里插入图片描述
在这里插入图片描述

def gcd(a: int, b: int) -> int:"""递归求解两个数的最大公约数 (GCD)。使用欧几里得算法通过递归的方式计算两个整数的最大公约数。当第二个数 b 为 0 时,最大公约数是第一个数 a。:param a: 第一个整数:param b: 第二个整数:return: 返回 a 和 b 的最大公约数"""if b == 0:return a  # 基本情况:当 b 为 0 时,a 是最大公约数else:# 递归调用:计算 b 和 a % b 的最大公约数return gcd(b, a % b)print(gcd(12, 16))  # 4def gcd2(a: int, b: int) -> int:"""非递归求解两个数的最大公约数 (GCD)。使用欧几里得算法通过迭代的方式计算两个整数的最大公约数。通过不断更新 a 和 b 直到 b 为 0,此时 a 就是最大公约数。:param a: 第一个整数:param b: 第二个整数:return: 返回 a 和 b 的最大公约数"""while b > 0:r = a % b  # 计算 a 除以 b 的余数a = b  # 更新 a 为 bb = r  # 更新 b 为余数return a  # 当 b 为 0 时,a 是最大公约数print(gcd2(12, 16))  # 4

2.1 动态规划之欧几里得算法-分数

class Fraction:def __init__(self, a: int, b: int):"""初始化一个分数对象,并将其化简为最简分数。:param a: 分子:param b: 分母"""self.a = aself.b = b# 计算最大公约数x = self.gcd(a, b)# 将分子和分母除以最大公约数,化简为最简分数self.a /= xself.b /= x@staticmethoddef gcd(a: int, b: int) -> int:"""非递归求解两个数的最大公约数 (GCD)。使用欧几里得算法通过迭代的方式计算两个整数的最大公约数。通过不断更新 a 和 b 直到 b 为 0,此时 a 就是最大公约数。:param a: 第一个整数:param b: 第二个整数:return: 返回 a 和 b 的最大公约数"""while b > 0:r = a % b  # 计算 a 除以 b 的余数a = b  # 更新 a 为 bb = r  # 更新 b 为余数return a  # 当 b 为 0 时,a 是最大公约数def __str__(self) -> str:"""返回分数的字符串表示形式。:return: 返回分数的字符串表示,例如 "3/4""""return f"{int(self.a)}/{int(self.b)}"@staticmethoddef zgs(a: int, b: int) -> int:"""计算两个数的最小公倍数 (Least Common Multiple, LCM)。使用公式 LCM(a, b) = abs(a * b) / GCD(a, b) 来计算最小公倍数。:param a: 第一个整数:param b: 第二个整数:return: 返回 a 和 b 的最小公倍数,类型为整数"""x = Fraction.gcd(a, b)  # 调用静态方法 gcd 计算最大公约数return a * b // x  # 根据公式计算最小公倍数,使用整数除法返回整数结果def __add__(self, other: 'Fraction') -> 'Fraction':# 3/5 + 2/7"""重载加法运算符,实现两个分数相加。通过计算两个分数的最小公倍数来统一分母,并计算新分数的分子。:param self: 第一个分数对象:param other: 第二个分数对象:return: 返回两个分数相加后的结果,作为新的 Fraction 对象"""a = self.a  # 当前分数的分子b = self.b  # 当前分数的分母c = other.a  # 另一个分数的分子d = other.b  # 另一个分数的分母denominator = self.zgs(b, d)  # 计算两个分数分母的最小公倍数numerator = a * denominator // b + c * denominator // d  # 计算新分数的分子,使用整数除法确保结果为整数return Fraction(int(numerator), int(denominator))  # 返回新的 Fraction 对象,表示两个分数相加的结果# f = Fraction(30, 16)
# print(f)  # 输出 15/8a = Fraction(3, 4)
b = Fraction(1, 2)
print(a + b)  # 5/6

3 RSA算法-密码于加密

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/1516244.html

相关文章

关于AR在医疗领域创新应用

AR技术在医疗领域创新应用,旨在展示AR技术如何为医疗行业带来革命性的变化,我们可以从以下几个方面入手: 一、引言 随着科技的飞速发展,增强现实(AR)技术正逐步渗透到医疗领域的各个环节,为患…

如何评估Redis的性能

如果系统中出现了大 key、热 key 等,往往会导致 Redis 变慢,但是这个慢该如何界定?多久算慢?1秒还是3秒? 这个肯定是没有标准答案,因为这个和你的硬件设备有关。 硬件差一些,平时响应时间都是…

ClickHouse与Elasticsearch:大数据时代的两大引擎比较

目录 1. 基本介绍 ClickHouse Elasticsearch 2. 优劣势分析 ClickHouse的优势 ClickHouse的劣势 Elasticsearch的优势 Elasticsearch的劣势 3. 应用案例 4. 总结与选择建议 随着大数据技术的不断发展,企业对数据分析和实时搜索的需求也日益增长。ClickH…

Qt简介----信号与槽与信号(Signals)

以下是为上述博客生成的目录: 目录 什么是Qt?为什么选择Qt? 2.1 跨平台支持2.2 丰富的模块2.3 强大的社区支持2.4 信号与槽机制 深入理解Qt的信号与槽机制 3.1 信号与槽简介3.2 为什么使用信号与槽?3.3 使用信号与槽的基本步骤 …

CSS新增的单位ch

在CSS中,ch 是一个相对单位,它代表数字0(零)的宽度,在当前的字体和字体大小下的度量。这个单位特别适用于需要基于字符宽度进行布局的场景,比如保持文本的垂直对齐或者在元素内部确保一定的空间以容纳文本字…

【UE5】库存系统——01

目录 步骤 一、项目准备 二、制作数据表 三、与场景物体交互 五、制作可交互的物品 步骤 一、项目准备 1. 新建一个项目,使用第一人称游戏模板,勾选初学者内容包 2. 新建一个蓝图类,父类选择“Actor组件” 这里命名为“Component_Inve…

暴雨受邀参加深圳市计算机行业协会会员大会暨资源对接会

8月23日,由深圳市计算机行业协会举办的会员大会暨资源对接会在深圳圆满落幕。活动旨在促进会员企业的资源对接,促进企业间高效合作,共同迎接计算机行业的发展机遇与挑战。来自计算机行业的众多领军企业、专家学者及行业精英齐聚一堂&#xff…

【C++】13.特殊类的设计

一、请设计一个类,不能被拷贝 拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可 C98 将拷贝构造函数与赋值运算符重载只声明不定义&a…

React 使用ref属性调用子组件方法(也可以适用于父子传参)

注意:①需使用hooks函数组件 ②使用了antDesign组件库(可不用) 如何使用 父组件代码 import React, { useState, useRef, useEffect } from react; import { Button } from antd; import Child from ./components/child;export defau…

vue3上传excel并在线预览

目录 前言 安装 xlsx 依赖 XLSX.utils.sheet_to_html XLSX.utils.sheet_to_json 前言 关于实现excel文档在线预览的做法,一种方式是通过讲文档里的数据处理成html,一种是将文档处理成图片进行预览,这里使用的是第一种。 安装 xlsx 依赖 …

【C语言篇】

C语言是一种广泛使用的计算机编程语言,它以其高效、灵活和功能强大而著称。以下是一些C语言中的常见知识点: 基本语法: 变量声明与初始化 数据类型(整型、浮点型、字符型等) 控制语句(if、for、while、do…

高可用 Go 服务开发

高可用的含义是尽量减少服务的不可用(日常维护或者突发系统故障)时长,提升服务的可用时长。如何衡量一个服务的可用性呢?或许你也听说过,通常企业可能会要求服务的可用性能能够达到三个 9(也就是 99.9%)或者 4个 9 &am…

Axios介绍;前后端分离开发的介绍;YAPI的使用;Vue项目简介、入门;Elementui的使用;nginx介绍

1 Ajax 1.1 Ajax介绍 1.1.1 Ajax概述 我们前端页面中的数据,如下图所示的表格中的学生信息,应该来自于后台,那么我们的后台和前端是互不影响的2个程序,那么我们前端应该如何从后台获取数据呢?因为是2个程序&#xf…

机器学习在旅游业的革新之旅

机器学习在旅游业的革新之旅 随着科技的飞速发展,尤其是人工智能(AI)技术的广泛应用,各个行业都迎来了前所未有的变革。其中,旅游业作为全球经济的重要支柱之一,更是受益匪浅。机器学习(Machin…

AWS SAM CLI 备忘单!

安装 AWS SAM CLI brew tap aws/tap brew 安装 aws-sam-cli 验证安装 $ sam --version 升级 SAM $ brew upgrade aws-sam-cli 您需要 AWS 凭证才能在 AWS 上工作。 构建并部署简单应用程序 $ sam init→ 下载示例应用程序 $ sam build→ 构建您的应用程序 $ sam deploy --guid…

绿色积分引领:我店平台的可持续消费革命

在当今数字化浪潮的推动下,“我店”凭借其创新的环保积分系统,在消费市场中脱颖而出,逐渐改变着市场的结构。本文将详细分析该平台的竞争优势、市场策略以及它如何利用创新手段塑造未来的消费趋势。 一、环保积分:消费体验革新的关…

永磁同步电机高性能控制算法(13)后续篇—— 基于高阶扩张状态观测器(ESO)的无模型预测控制(MFPC)

1.前言 前文已经介绍过了高阶ESO相对于传统ESO的优势。 https://zhuanlan.zhihu.com/p/703039702https://zhuanlan.zhihu.com/p/703039702 但是当时搭的ESO有点问题。把公式修正之后,发现前文用的改进四阶ESO无法使用。 今天来解释一下为什么改进4阶ESO无法使用…

SQL, 有终止条件的多次累计计算

MSSQL数据库的data表存储了多人上电梯的情况,turn表示进电梯的顺序。电梯最大承重1000公斤,每趟能上的人数有限,超重的人要等下一趟。nameweightturnAlice2501Bob1702Alex3503John4004Winston5005Marie2006 请计算每趟电梯最后一个进入的人的…

笔记整理—uboot启动过程(5)BL2板级初始化

上一章说到了uboot在BL2阶段大概都要干什么,也说到了为了实现这些要先进行内存排布,实现了这些后便可实现BL2部分的板级初始化。首先先来看一下init_fnc_ptr函数指针。 for(init_fnc_ptrinit_sequence;*init_fnc_ptr;init_fnc_ptr){if((*init_fnc_ptr)(…

gitlab迁移至新的服务器

第一步,查看旧服务器的gitlab版本,在新服务器上安装一个相同版本的 cat /opt/gitlab/embedded/service/gitlab-rails/VERSION wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el8/gitlab-ce-14.9.3-ce.0.el8.x86_64.rpm rpm -ivh gitlab-ce-1…