最大公共子序列c++

最大公共子序列c++

  • 概念
    • 基本的概念
  • 递归
    • 算法
    • 代码
    • 优化
    • map基础
    • 优化代码

概念

基本的概念

  • 子序列: 由原序列中若干个元素组成,元素可以不连续,但和原序列的顺序一致。
  • 最长公共子序列: 一个序列即是甲序列的子序列,也是乙序列的子序列,则该序列称为为甲和乙的公共子序列。长度最长的公共子序列,即最长公共子序列。
  • 两个序列的公共子序列不一定是唯一的。

递归

算法

  • lcs(s1,s2)表示:串s1和s2的最大公共子序列长度,并返回其值
  • 先比较两个串的首字符,如果相等,递归实现lcs(s1+1,s2+1)+1即可
  • 如果不相等,则返回lcs(s1,s2+1),lcs(s1+1,s2)中较大的。
    在这里插入图片描述
  • 由上图可以看出,最大公共子序列的值为3,但不唯一,abc,bca的长度都是3。

代码

#include<iostream>
using namespace std;
int lcs(const char* a,const char* b){
	if(*a == 0 || *b==0) 
		return 0;
	if(*a==*b)
		return lcs(a+1,b+1)+1;
	return max(lcs(a,b+1),lcs(a+1,b));
} 
int main(){
	cout<<lcs("axbcydz","xayybcxd")<<endl;
	return 0;
}

优化

  • 递归的优点是思路简单,但是耗费资源,重复递归调用。
  • 如下图,草拟相同圈处是重复递归计算的地方,如果串长些,那么这种重计划量将非常繁巨,以致电脑无法计算。
    在这里插入图片描述
  • 所以需改进,改进的方法是,相同的串相互比较求最大公共子序列时,就将其存储起来,放入map,下次再遇到相同的2个串比较时,直调从map中取值。
  • 因为加入了参递,所以递归函数需要增参。
  • 递归函数f(m,s1,k1,s2,k2)
  • 参数说明。m是map记录着2个子串的最大公共子序列,s1、s2是子串,k1、k2是从子串的哪个下标开始比较。
  • 即只需以k1\k2的位置作为键,递归函数的返回值(最大公共子序列的长度)作为值,存入map中即可。

map基础

  • 头文件,#include
  • map存取键-值对,查找速度快。键需能比较,此应用中键为2个int,int。
  • stl中的pair可以保存<int,int>。定义为
#include <utility> // 包含 std::pair 的头文件
#include <iostream>
using namespace std;
int main() {
    // 直接初始化 std::pair
    pair<int, double> pair1(1, 3.14);
    // 使用 std::make_pair 函数初始化 std::pair
    pair<string, int> pair2 = make_pair("Kimi", 2024);
    // 访问 pair 的元素
    cout << "pair1: " << pair1.first << ", " << pair1.second << endl;
    cout << "pair2: " << pair2.first << ", " << pair2.second << endl;
    // 修改 pair 的元素
    pair1.first = 2;
    pair2.second = 2025;

    return 0;
}
  • map中统计键pair出现的次数
#include <iostream>
#include <map>
using namespace std;
int main() {
    map<pair<int, int>, string> map;
    // 插入键值对
    map[make_pair(1, 2)] = "12";
    map[make_pair(1, 2)] = "21"; // 注意:这实际上是更新了键(1, 2)的值
    map[make_pair(3, 4)] = "34";
    // 要查找的键
    pair<int, int> key_to_count(1, 2);
    // 使用count查找键
    size_t count = map.count(key_to_count);
    cout << "The key (" << key_to_count.first << ", " << key_to_count.second << ") appears " << count << " times." << endl;
    return 0;
}
  • map中查找pair对
#include <iostream>
#include <map>
#include <utility> // For std::pair
using namespace std;
int main() {
    // 创建一个map,键为pair<int, int>,值为string
    map<pair<int, int>, string> map;
    // 插入键值对
    map[make_pair(1, 2)] = "12";
    map[make_pair(3, 4)] = "34";
    // 要查找的键
    pair<int, int> key_to_find(1, 2);
    // 使用find查找键
    auto it = map.find(key_to_find);
    if (it != map.end()) {
        cout << "Found key: (" << it->first.first << ", " << it->first.second << ") with value: " << it->second << endl;
    } else {
        cout << "Key not found." << endl;
    }
    return 0;
}
  • map遍历
#include <iostream>
#include <map>

int main() {
    std::map<int, std::string> myMap;
    // 插入一些键值对
    myMap[1] = "one";
    myMap[2] = "two";
    myMap[3] = "three";
    // 使用 begin() 获取指向第一个元素的迭代器
    auto it = myMap.begin();
    // 检查迭代器是否不是 end()(即检查 map 是否不为空)
    if (it != myMap.end()) {
        // 使用迭代器访问并打印第一个元素
        std::cout << "The first key-value is: " << it->first << " => " << it->second << std::endl;
    }
    // 使用范围基于的 for 循环遍历 map
    for (const auto& pair : myMap) {
        std::cout << pair.first << " => " << pair.second << '\n';
    }
    return 0;
}
  • 自定义pair对
#include <iostream>
#include <map>
using namespace std;
// 定义一个结构体作为键
struct IntPair {
    int first;
    int second;
    // 必须定义比较运算符,以便map可以比较键
    bool operator<(const IntPair& other) const {
        return first < other.first || (first == other.first && second < other.second);
    }
};
int main() {
    // 定义一个map,键为IntPair,值为string
    std::map<IntPair, std::string> map;
    // 插入键值对
    map[{1, 2}] = "12";
    map[{3, 4}] = "34";
    // 访问键值对
    for (const auto& kv : map) {
        cout << "Key: (" << kv.first.first << ", " << kv.first.second << ") Value: " << kv.second << endl;
    }

    return 0;
}

优化代码

#include<iostream>
#include<map>
using namespace std;
int f(map<pair<int,int>,int>& m,const char* s1,int k1,const char* s2,int k2){
	if(s1[k1]==0 || s2[k2]==0)
		return 0;
	pair<int,int> p(k1,k2); //构建子串pair对 
	if(m.count(p))//查找map中是否有相应的子串最大公共子序列值
		return m[p];//如果存储了,则直接返回子序列长度,不必再递归计算 
	//map中未记录,才计算最大公共子序列的长度 
	if(s1[k1]==s2[k2]){ 
		int t=f(m,s1,k1+1,s2,k2+1)+1;
		m[make_pair(k1,k2)]=t;
		return t;
	}
	int t1=f(m,s1,k1+1,s2,k2);
	int t2=f(m,s1,k1,s2,k2+1);
	int t=max(t1,t2);
	m[make_pair(k1,k2)]=t;
	return t;
}
int lcs(const char* s1,const char* s2){
//	map<int,int>ma;
	map<pair<int,int>,int> m;//定义一个map,键为pair<int,int>,值为int。 
	return f(m,s1,0,s2,0);
} 
int main(){
	cout<<lcs("axbcydz","xayybcxd")<<endl;
	cout<<lcs("axbcydzaxbcydz","xayybcxdaaaaabbbxxccc")<<endl;
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DNDC模型下载与安装;土壤碳储量;点尺度和区域尺度模拟;气象数据、土地数据、土壤数据处理、农田减排潜力分析、温室气体排放分析等

实现美丽中国建设目标&#xff0c;“双碳”行动将会发挥非常重要的作用。碳循环的精确模拟是实现“双碳”行动的关键。DNDC&#xff08;Denitrification-Decomposition&#xff0c;反硝化-分解模型&#xff09;是目前国际上最为成功的模拟生物地球化学循环的模型之一&#xff0…

spark:Structured Streaming介绍

文章目录 1. Structured Streaming介绍1.1 实时计算和离线计算1.1.1 实时计算1.1.2 离线计算 1.2 有界和无界数据 2. 简单使用3. 编程模型4. 数据处理流程4.1 读取数据Source4.1.1 文件数据处理 4.2 计算操作 Operation4.3 数据输出 Sink4.3.1 输出模式4.3.2 指定输出位置4.3.3…

Html/Vue浏览器下载并重命名文件

Html/Vue浏览器下载并重命名文件 row是上方图片的数据对象 download(row) {const link document.createElement(a);link.style.display none;// 设置下载地址link.setAttribute(href, row.url);// 设置文件名(这里可以重新设置名字&#xff0c;下载之后的文件就是你重新命名…

【数据结构与算法】链表(上)

记录自己所学&#xff0c;无详细讲解 无头单链表实现 1.项目目录文件 2.头文件 Slist.h #include <stdio.h> #include <assert.h> #include <stdlib.h> struct Slist {int data;struct Slist* next; }; typedef struct Slist Slist; //初始化 void SlistI…

死锁和活锁和线程饥饿

死锁 死锁是指两个或两个以上的线程在执行过程中&#xff0c;因争夺资源而造成的一种相互等待的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。 原因&#xff1a;两个或两个以上的线程共同访问两个或多个相同的资源&#xff08;如对象锁&#xff09;&#…

Unity使用TriangleNet参考

TriangleNet下载如下&#xff1a; TriangleNet 效果如下&#xff1a; 代码参考如下&#xff1a; using System.Collections.Generic; using UnityEngine; using TriangleNet.Geometry;public class TestTriangleNet : MonoBehaviour {[SerializeField]Material material;voi…

耳夹式耳机哪个品牌音质好?五大优质音质的耳夹式耳机!

随着健康理念的传播&#xff0c;运动健身成为大众追求高品质生活的重要部分。传统耳机在运动场景下有局限性&#xff0c;稳定性差、清洁不便&#xff0c;影响运动体验。这时&#xff0c;耳夹式耳机出现&#xff0c;以独特设计和传音方式重塑运动音乐享受&#xff0c;无需入耳&a…

游戏推荐业务中基于 sentinel 的动态限流实践

作者&#xff1a;来自 vivo 互联网服务器团队- Gao Meng 本文介绍了一种基于 sentinel 进行二次开发的动态限流解决方案&#xff0c;包括什么是动态限流、为什么需要引入动态限流、以及动态限流的实现原理。 一、背景 1.1 当前的限流方案 随着互联网的发展及业务的增长&…

Flythings学习(四)串口通信

文章目录 1 串口编程基本步骤1.1 打开串口1.2 配置串口 1.3 读串口1.4 发送串口1.5 关闭串口 2 综合使用3 如何在软件上保证串口稳定通信4 flythings中的串口通讯5 协议接收部分使用和修改方法6 通讯协议数据怎么和UI控件对接 1 串口编程基本步骤 串口通信有5个步骤 1.打开串口…

Telegram——Bot 机器人/小程序入门指南

一、Bot 介绍 在 TG 中,机器人可以用于接收和发送消息、管理群组(在有权限的情况下可以封禁用户、删除消息、置顶消息等)、通过API进行编程操作、使用 Inline 查询功能在不同的聊天室中提供查询服务、创建自定义键盘按钮、发出账单并收款、接入小程序游戏等。 然而,Bot 默…

单片机中断概念以及示例

中断允许控制寄存器 CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的。 EX0(IE.0)&#xff0c;外部中断0允许位&#xff1b;EX01&#xff0c;打开外部中断0中断&#xff1b;EX00关闭外部中断0中断。 ET0(IE.1)&#xff0c;定时/计数器T0中断允许…

沪尚茗居装修秘籍:嵌入式蒸烤箱,让厨房生活更精彩

在装修厨房时&#xff0c;选择一款合适的嵌入式蒸烤箱不仅能提升烹饪效率&#xff0c;还能为厨房增添一份现代感。沪尚茗居深知用户对厨房电器的需求&#xff0c;从实际出发&#xff0c;为用户推荐选购嵌入式蒸烤箱的实用技巧&#xff0c;让厨房生活更加美好。    首先&…

Real-World Image Variation by Aligning Diffusion Inversion Chain

https://proceedings.neurips.cc/paper_files/paper/2023/file/61960fdfda4d4e95fa1c1f6e64bfe8bc-Paper-Conference.pdfhttps://rival-diff.github.io/ 问题引入 针对的是image varation generation这个任务&#xff0c;tuning free的&#xff1b; methods C C C表示condit…

【closerAI ComfyUI】电商模特一键换装解决方案来了!细节到位无瑕疵!再加上flux模型加持,这个工作流不服不行!

不得了了兄弟们。这应该是电商界的福音&#xff0c;电商模特一键换装解决方案来了&#xff01;细节到位无瑕疵&#xff01;再加上flux模型加持&#xff0c;这个工作流不服不行&#xff01; 这期我们主要讨论如何使用stable diffusion comfyUI 制作完美无瑕疵的换装工作流。** …

《Linux从小白到高手》综合应用篇:详解Linux系统调优之服务器硬件优化

List item 本篇介绍Linux服务器硬件调优。硬件调优主要包括CPU、内存、磁盘、网络等关键硬件组。 1. CPU优化 选择适合的CPU&#xff1a; –根据应用需求选择多核、高频的CPU&#xff0c;以满足高并发和计算密集型任务的需求。CPU缓存优化&#xff1a; –确保CPU缓存&#x…

C++和OpenGL实现3D游戏编程【连载15】——着色器初步

&#x1f525;C和OpenGL实现3D游戏编程【目录】 1、本节实现的内容 上一节我们介绍了通过VBO、VAO和EBO怎样将顶点发送到GPU显存&#xff0c;利用GPU与显存之间的高效处理速度&#xff0c;来提高我们的图形渲染效率。那么在此过程中&#xff0c;我们又可以通过着色器&#xff…

【C++网络编程】(二)Linux平台下UDP客户/服务端程序

Linux平台下UDP客户/服务端程序 图片来源&#xff1a;https://subingwen.cn/linux/udp/ UDP服务器无法直接检测客户端断开连接。 UDP 服务端 server.cpp #include <iostream> #include <cstdlib> // std::exit #include <cstring> // memset #i…

【数据结构与算法】单链表探秘:解锁数据结构中的灵动链条

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 一.单链表初探&#xff1a;构建数据结构的基石 1.1 单链表的概念及结构 1.2 节点的理解 1.3 链表的性质 二.单链表的作用&#xff1a;为何它是数据处理的优选 2.1 动态内存管理&#xff1a;内存世界的魔术师 2.2 高效的…

篇章九 【NPM】包管理工具

文章目录 一、认识NPM二、npm 镜像的设置与查看三、安装 NPM 工具1. 下载Node.js安装包2. 打开下载好的安装程序&#xff0c;点击下一步3. 选择接受许可协议&#xff0c;点击下一步4. 选择自己的安装路径&#xff08;默认是c盘&#xff09;&#xff0c;选择完成后&#xff0c;点…

喜讯AAA级!国信华源荣获全国水利建设信息化3A级信用

近日&#xff0c;中国水利工程协会发布了《2024年度水利建设市场主体&#xff08;供货、信息化单位&#xff09;信用评价结果公示》&#xff0c;国信华源荣获2024年度全国水利建设信息化单位AAA级信用评价。这一荣誉不仅是对国信华源在水利建设领域信息化能力和诚信经营的肯定&…