跟我学C++中级篇——容器的连接
一、数据的整合
在实际的开发场景中,经常可以遇到以下的情况:有几个地方的数据需要整合在一起。解决办法也有很多,在不同的层面有不同的解决方式。比如经过清洗可以把非关系型数据转为关系型数据。但在底层编程的情况中会发现有几情况:
1、几个数组之间的合并。
当然前提是这些数组存储的数据是兼容的
2、几个容器间的合并
它们之间的KEY和VALUE也要有兼容的数据类型
3、混合合并
可能需要做一些简单的数据处理,然后也可以合并在一起,比如数组数据,增加一个KEY(可以利用索引),就可以合并到容器中,反过来也可以考虑。
其实上面列举这么几种,本质就是把数据放到一个容器(广泛意义上的容器)中,这样方便程序的处理。比如有两个List,连接到一起一后就方便进行排序等算法的操作。
二、容器连接的基础方法
1、循环处理
这是最容易想到的方法 :
#include <iostream>
#include <unordered_map>
std::unordered_map<int, int> unmap{{1, 100}, {2, 200}};
int insertMap(std::unordered_map<int, int> &map) {if (map.size() < 1) {return 0;}for (auto &[k, v] : map) {unmap.emplace(k, v);}return unmap.size();
}int main(void) {std::unordered_map<int, int> map{{3, 300}, {4, 400}};size_t count = insertMap(map);std::cout << "new map size:" << count << std::endl;return 0;
}
2、 std::merge
它有两种合并的接口,一种是使用全局的merge;一种是使用容器自身包含的:
//map自身
#include <iostream>
#include <map>
#include <string>int main()
{std::map<int, std::string> ma{{1, "apple"}, {5, "pear"}, {10, "banana"}};std::map<int, std::string> mb{{2, "zorro"}, {4, "batman"}, {5, "X"}, {8, "alpaca"}};std::map<int, std::string> u;u.merge(ma);std::cout << "ma.size(): " << ma.size() << '\n';u.merge(mb);std::cout << "mb.size(): " << mb.size() << '\n';std::cout << "mb.at(5): " << mb.at(5) << '\n';for (auto const& kv : u)std::cout << kv.first << ", " << kv.second << '\n';
}
//全局
#include <algorithm>
#include <iterator>
#include <list>
template <typename T> void printList(const T &con, const char *c) {std::copy(con.cbegin(), con.cend(), std::ostream_iterator<typename T::value_type>(std::cout, c));std::cout << std::endl;
}
void stdMergeList() {std::list<int> l1{0, 1, 6, 3, 9, 7};std::list<int> l2{16, 11, 18, 35, 66};std::list<int> l3{};std::merge(l1.begin(), l1.end(), l2.begin(), l2.end(), std::back_inserter(l3));printList(l3, " ");
}int main(void) {stdMergeList();return 0;
}
上面的例程都比较简单,一看就明白。不过需要注意的是,有些小细节可能比较麻烦,比如在上面的使用全局处理时,如果插入到l2或l1中会是什么情况?可以试试。
另外还有一种方式就是使用C++17中的Node Handle的机制进行处理。
三、Node Handle
C++17中的Node handle(节点句柄),其实更应该说是一种机制而非方法。它主要用来处理基于结点的数据结构,常见的就是关联容器,如map,set等。它可以用Node Handle句柄来处理未指定类型的对象提取的节点。先看一个cppreference上的例子:
#include <algorithm>
#include <iostream>
#include <string_view>
#include <unordered_map>void print(std::string_view comment, const auto& data)
{std::cout << comment;for (auto [k, v] : data)std::cout << ' ' << k << '(' << v << ')';std::cout << '\n';
}int main()
{std::unordered_map<int, char> cont{{1, 'a'}, {2, 'b'}, {3, 'c'}};print("Start:", cont);// Extract node handle and change keyauto nh = cont.extract(1);nh.key() = 4;print("After extract and before insert:", cont);// Insert node handle backcont.insert(std::move(nh));print("End:", cont);
}
代码非常简单,大家一看就明白了。
四、分析
如果使用上面基础的连接方法,问题是没有什么大问题。但在实现上会有些让开发者不舒服的地方。比如循环方式插入,看似简单明了,但在底层大量进行了内存的分配和拷贝(移动),这会导致在某些情况下出现性能的瓶颈;而使用merge虽然有些进步,但并没有从本质解决,同时它还引入了一些场景的限制。比如全局的情况就只能使用有序的容器。这些细节如果再遇到复杂的应用场景如多线程等情况,一不小心可能就引入了错误。
而使用Node Handle就比较灵活方便,由于其只是Move元素,所以其效率和内存处理就简单和快捷许多。它利用了extract和insert函数,指向性非常准确和明显,即使出现异常也容易发现,非常易于维护。正如前面所分析,简单是王道!
不过使用此种机制也要小心一些重复插入的问题,文档说这种情况可能会产生UB行为。同时,仍然如前面所讲,合并的前后必须保证数据类型的一致性。最后切记切记,STL的容器一般都是非线程安全的。
五、总结
其实编程就是从这些小的功能一点点的把基础打好的。正如前面的容器中的insert,push_back和后来的emplace_back。STL库中为什么要有这么多的方法来处理元素的插入?把这些细节把握住就深刻明白了C++中容器组织的过程。从另外一个角度打开学习的途径。
人生而有涯,而学之也无涯!
相关文章:
跟我学C++中级篇——容器的连接
一、数据的整合 在实际的开发场景中,经常可以遇到以下的情况:有几个地方的数据需要整合在一起。解决办法也有很多,在不同的层面有不同的解决方式。比如经过清洗可以把非关系型数据转为关系型数据。但在底层编程的情况中会发现有几情况&#…...
java求职学习day15
多线程 1 基本概念 1.1 程序和进程的概念 (1)程序 - 数据结构 算法,主要指存放在硬盘上的可执行文件。 (2)进程 - 主要指运行在内存中的可执行文件。 (3)目前主流的操作系统都支持多进程&a…...
【脚本】如何禁用谷歌浏览器自动更新
这里写自定义目录标题 问题描述解决方法代码 问题描述 最近更新系统以后,发现chrome老是自己更新,导致我的代码也得跟着他更新,就跟一个拜托不掉的狗皮膏药一样。 解决方法 于是我写了一个脚本,以下代码都是bash代码࿰…...
【Linux】华为服务器使用U盘安装统信操作系统
目录 一、准备工作 1.1 下载UOS官方系统 1.2制作启动U盘 1.3 服务器智能管理系统iBMC 二、iBMC设置U盘启动 一、准备工作 1.1 下载UOS官方系统 服务器CPU的架构是x86-64还是aarch64),地址:统信UOS生态社区 - 打造操作系统创…...
WPF3-在xaml中引用其他程序集的名称空间
1. 如何在XAML里引用类库中的名称空间和类2. 小结 1. 如何在XAML里引用类库中的名称空间和类 首先需要记住一点:把类库引用到项目中是引用其中名称空间的物理基础,无论是C#还是XAML都是这样。 一旦将一个类库引用进程序,就可以引用其中的名…...
Python 在Word中添加、或删除超链接
在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超链接,用户可以轻松地导航到相关信息,从而增强文档的互动性和可读性。本文将介绍如何使用Python在Word中添加超链接、或删除Word文档中的超…...
基于 WPF 平台使用纯 C# 实现动态处理 json 字符串
一、引言 在当今的软件开发领域,数据的交换与存储变得愈发频繁,JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,以其简洁、易读、便于解析和生成的特点,被广泛应用于各种应用程序中。在 W…...
「全网最细 + 实战源码案例」设计模式——单例设计模式
核心思想: 属于创建型设计模式,核心目的是确保一个类在整个程序运行期间只有一个实例,并提供一个全局访问点来获取该实例。 控制共享资源的访问(如数据库链接、配置管理、日志处理器等) 真实世界类比:政府…...
第01章 19 通过点数据逐级构建球体体数据的综合性小例子
用VTK库来创建一个三维图像数据(vtkImageData),并填充标量数据以表示一个球体的体数据。球的半径为50,体数据的空间间隔为1.0/1000。 首先,我需要包含VTK的头文件,并且创建一个vtkImageData对象。然后&…...
CVE-2024-23897-Jenkins任意文件读取漏洞复现
content Jenkins是什么CVE-2024-23897总结修复建议 Jenkins是什么 Jenkins是一人基于Java开发的、可扩展的持续集成引擎,用于持续、自动地构建/测试软件项目,可以监控一些定时执行的任务。 官网文档: Jenkins是一款开源 CI&CD 软件&…...
前端react后端java实现提交antd form表单成功即导出压缩包
前端(React Ant Design) 1. 创建表单:使用<Form>组件来创建你的表单。 2. 处理表单提交:在onFinish回调中发起请求到后端API,并处理响应。 import React from react; import { Form, Input, Button } from ant…...
基于ESP32的桌面小屏幕实战[6]:环境搭建和软件基础
摘要 本文分为两部分:Linux开发环境搭建和软件基础。Linux开发环境搭建介绍了Ubuntu虚拟机安装及SSH、Samba配置,可以实现用VSCode操作虚拟机。为了后续工作,搭建了乐鑫ESP32 SDK环境。软件基础介绍了Linux开发常用的软件基础,包…...
接口(完)
大家好,今天我们着重来总结一下接口的知识,并且将接口和抽象类的区别罗列一下,帮助我们更好的认识抽象类和接口。 2.7 抽象类和接口的区别. 抽类和接口都是Java中多态的常见使用方式,都需要重点掌握,同时又要认清两者的区别(重要!!…...
数据结构——实验七·排序
欢迎各位大佬们来到Tubishu的博客🌟 Tubishu是一名计算机本科生,不定期发送一些在学校的成果供佬们消遣~希望能为佬的编程之路添砖加瓦⭐🔥 求各位大佬们垂怜🔥点赞评论一下呗🔥🔥 本文专栏 ➡️ 数据结构 …...
JVM堆空间
JVM(Java虚拟机)堆空间是Java内存管理的核心区域之一,用于存储Java对象实例。以下是关于JVM堆空间的详细介绍: 1. 堆空间的作用 • 存储对象实例:几乎所有的Java对象实例(通过new关键字创建的对象…...
【详细】SSH公私钥认证与渗透测试攻击场景
SSH(Secure Shell)是一个用于远程登录和执行命令的网络协议,其认证方式通常有两种:基于密码的认证和基于公私钥的认证。本文将详细介绍SSH公私钥认证机制,并探讨在渗透测试场景中,如何利用对靶机具有读取和…...
常见的多媒体框架(FFmpeg GStreamer DirectShow AVFoundation OpenMax)
1.FFmpeg FFmpeg是一个非常强大的开源多媒体处理框架,它提供了一系列用于处理音频、视频和多媒体流的工具和库。它也是最流行且应用最广泛的框架! 官方网址:https://ffmpeg.org/ FFmpeg 的主要特点和功能: 编解码器支持: FFmpe…...
C++异步future
🌎 C11异步futrue 文章目录: C11异步futrue future介绍 应用场景 future操作 std::async函数模版 std::packaged_task类模版 std::promise类模版 🚀future介绍 std::future是C11标准库…...
Oracle 12c 中的 CDB和PDB的启动和关闭
一、简介 Oracle 12c引入了多租户架构,允许一个容器数据库(Container Database, CDB)托管多个独立的可插拔数据库(Pluggable Database, PDB)。本文档旨在详细描述如何启动和关闭CDB及PDB。 二、容器数据库 (CDB) 2.1…...
Vue组件开发-使用 html2canvas 和 jspdf 库实现PDF文件导出 设置页面大小及方向
在 Vue 项目中实现导出 PDF 文件、调整文件页面大小和页面方向的功能,使用 html2canvas 将 HTML 内容转换为图片,再使用 jspdf 把图片添加到 PDF 文件中。以下是详细的实现步骤和代码示例: 步骤 1:安装依赖 首先,在项…...
Tailscale打洞失败太慢?手把手教你用Docker部署derper自建中转,告别国际绕行
Tailscale网络优化实战:用Docker自建derper中转节点提升连接速度 Tailscale作为现代零配置组网工具,其基于WireGuard协议的P2P直连特性确实令人惊艳——直到你发现两台设备之间的打洞成功率只有60%,而剩余40%的流量不得不绕行官方位于海外的中…...
OpenClaw飞书集成实战:Qwen3-VL:30B智能对话与任务触发
OpenClaw飞书集成实战:Qwen3-VL:30B智能对话与任务触发 1. 为什么选择OpenClaw飞书组合 去年夏天,我接手了一个棘手的任务:团队每天产生上百条会议录音和杂乱无章的文档碎片,需要人工整理成结构化会议纪要。当我尝试用传统RPA工…...
沃虎电子:SFP连接器在高速光模块中的应用与选型要点
SFP(Small Form-factor Pluggable)连接器是现代光通信设备的核心接口组件,广泛应用于交换机、服务器、光模块等设备。随着数据中心向400G/800G演进,SFP连接器的性能要求不断提升。本文从工程实践角度,系统介绍SFP连接器…...
OpenClaw多终端访问:远程控制GLM-4.7-Flash助手方案
OpenClaw多终端访问:远程控制GLM-4.7-Flash助手方案 1. 为什么需要远程访问OpenClaw? 去年冬天的一个深夜,我正在外地出差,突然接到同事紧急需求——需要从公司内网服务器提取一份关键数据报告。当时我的OpenClaw助手部署在家里…...
OpenClaw语音交互扩展:百川2-13B+Whisper实现语音指令控制
OpenClaw语音交互扩展:百川2-13BWhisper实现语音指令控制 1. 为什么需要语音交互能力 去年冬天的一个深夜,我正在调试OpenClaw的自动化脚本,双手因为长时间敲键盘已经有些僵硬。突然想到:如果能让AI听懂我的语音指令直接执行任务…...
VRCT:打破虚拟社交语言壁垒的实时翻译解决方案
VRCT:打破虚拟社交语言壁垒的实时翻译解决方案 【免费下载链接】VRCT VRCT(VRChat Chatbox Translator & Transcription) 项目地址: https://gitcode.com/gh_mirrors/vr/VRCT 在全球化的虚拟社交平台VRChat中,语言差异常常成为跨文化交流的最…...
软件外包公司的“末路”:印度同行都慌了?——软件测试从业者的专业视角
在当今数字化浪潮中,软件外包行业曾是全球经济的重要引擎,尤其以印度为代表的外包巨头,凭借低成本人力优势主导了全球市场。然而,随着人工智能(AI)技术的迅猛发展,这一模式正面临前所未有的挑战…...
Python实战:5分钟搞定Paillier同态加密的安装与基础使用(附避坑指南)
Python实战:5分钟搞定Paillier同态加密的安装与基础使用(附避坑指南) 隐私计算领域近年来发展迅猛,而同态加密作为其核心技术之一,正在金融、医疗等行业的数据协作场景中发挥越来越重要的作用。Paillier算法作为支持加…...
大语言模型训练中的显存占用与优化方法简述
在进行大语言模型(LLM)的微调或预训练时,显存(VRAM)不足通常是首要面临的问题。为了在有限的硬件资源下完成训练,了解显存的具体去向以及相应的优化技术是比较基础的工作。 从模型训练的流程来看ÿ…...
5步快速解锁付费内容:bypass-paywalls-chrome-clean终极指南 [特殊字符]
5步快速解锁付费内容:bypass-paywalls-chrome-clean终极指南 🚀 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在信息爆炸的时代,你是否经常遇到优…...
