C++之STL整理(1)之vector、map数据结构初识

C++之STL整理(1)之vector、map数据结构初识

注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构


C++ 的 STL

  • C++之STL整理(1)之vector、map数据结构初识
  • 一、STL概要,初识STL
    • 1、STL之容器
      • (1)序列式容器
      • (2)关联式容器
    • 2、算法
    • 3、迭代器与遍历
      • (1)对vector的遍历
      • (2)对map的遍历
      • (3)对set的遍历
    • 4、仿函数
    • 5、适配器
    • 6、空间配置器
  • 总结


提示:本文为 C++ 中 vector、map、set的写法和举例


一、STL概要,初识STL

  STL,即Standard Template Library,标准模板库,是C++标准库的一个重要组成部分。它是一个可复用的封装好的组件库,同时也是一个包罗数据结构与算法的软件框架。STL为C++程序员们提供了一个可扩展的应用框架,高度体现了软件的封装性与可复用性。

STL包含了诸多在计算机科学领域里所常用的数据结构基本算法,提供了许多通用的模板类和函数,用于实现常用的数据结构和算法。STL的一个重要特点是数据结构和算法的分离,它允许程序员编写通用的代码,即可适用于不同的数据类型,而不必为每种类型编写不同的代码。

STL的六大组件包括容器(Containers)、迭代器(Iterators)、算法(Algorithms)、仿函数(Functors)、适配器(Adapters)和空间配置器(Allocators)

其中,
容器负责存储和管理数据,每种容器相当于定义好的一个反映数据结构的类(模板类):如字符串(string)、向量(vector)、列表(list)、双端队列(deque)、栈(stack)、队列(queue)、优先队列(priority_queue)、集合(set)、映射(map)等。
迭代器则用于遍历容器中的元素。
算法是对容器中的数据进行操作的函数,分为质变算法和非质变算法
仿函数和行为类似于函数的对象,可以作为算法的参数以定制算法的行为。
适配器用于修改容器或迭代器的接口以提供不同的功能。
空间配置器则负责内存的分配和释放。

1、STL之容器

容器:存储数据的数据结构类,如vector、deque、list等,C++的string数据结构也是一个封装好的容器。

算法:对容器中的数据进行操作的函数模板,如排序、查找等。

迭代器:提供一种方法来访问容器中的元素。

仿函数:行为类似函数的对象,可以作为算法的参数来定制算法的行为。

适配器:用于修改容器或迭代器的接口,以提供不同的功能。

空间配置器:负责内存分配和释放的组件,通常不需要直接操作。

(1)序列式容器

序列式容器中的元素按照插入顺序进行存储

Vector容器:又叫动态数组,支持随机访问。

#include <vector>  
#include <iostream>  int main() {  std::vector<int> vec = {1, 2, 3, 4, 5};  for (const auto& element : vec) {  std::cout << element << " ";  }  return 0;  
}

Deque容器:双端队列,支持在头部和尾部进行插入和删除操作。

#include <deque>  
#include <iostream>  int main() {  std::deque<int> deq = {1, 2, 3, 4, 5};  deq.push_front(0); // 在头部插入元素  deq.push_back(6); // 在尾部插入元素  for (const auto& element : deq) {  std::cout << element << " ";  }  return 0;  
}

List容器:双向链表,支持在任意位置进行插入和删除操作。

#include <list>  
#include <iostream>  int main() {  std::list<int> lst = {1, 2, 3, 4, 5};  lst.push_front(0); // 在头部插入元素  lst.push_back(6); // 在尾部插入元素  for (const auto& element : lst) {  std::cout << element << " ";  }  return 0;  
}

(2)关联式容器

关联式容器中的元素通过关键字进行存储和访问。关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有维持元素置入容器时的逻辑顺序

Set/multiset容器:集合,存储唯一或重复的元素。

#include <set>  
#include <iostream>  int main() {  std::set<int> s = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};  for (const auto& element : s) {  std::cout << element << " ";  }  return 0;  
}

Map/multimap容器:键值对集合,存储不重复/重复的键及其对应的值。

#include <map>  
#include <iostream>  int main() {  std::map<std::string, int> m = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}};  for (const auto& pair : m) {  std::cout << pair.first << ": " << pair.second << std::endl;  }  return 0;  
}

2、算法

质变算法
质变算法会改变容器内元素的内容。

拷贝算法:例如std::copy。

#include <vector>  
#include <algorithm>  
#include <iostream>  
#include <iterator>  int main() {  std::vector<int> src = {1, 2, 3, 4, 5};  std::vector<int> dst(src.size());  std::copy(src.begin(), src.end(), dst.begin());  for (const auto& element : dst) {  std::cout << element << " ";  }  return 0;  
}

非质变算法
非质变算法不会改变容器内元素的内容。

查找算法:例如std::find。
继续上面的内容讲解,我们来看非质变算法的一个例子——std::find。

#include <vector>  
#include <algorithm>  
#include <iostream>  int main() {  std::vector<int> vec = {1, 2, 3, 4, 5};  auto it = std::find(vec.begin(), vec.end(), 3); // 查找值为3的元素  if (it != vec.end()) {  std::cout << "Found: " << *it << std::endl;  } else {  std::cout << "Not found" << std::endl;  }  return 0;  
}

在这个例子中,std::find算法在vec容器中查找值为3的元素,并返回一个迭代器指向找到的元素。如果找不到,则返回end()迭代器。

3、迭代器与遍历

迭代器提供了一种方法来遍历容器中的元素。上面的算法例子中已经展示了如何使用冒号遍历,当然数组可以用[]遍历,STL提供的新的遍历方法:使用迭代器。迭代器类似于指针,但提供了更安全的访问方式。STL提供了不同类型的迭代器,如输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器等,每种类型支持不同的操作集。它使得程序员能够遍历容器(如vector、map、set等)中的元素,同时隐藏了底层数据结构的实现细节。迭代器就像是指向容器中元素的指针或引用,但它比指针更加类型安全,并且可以处理不同类型的容器。
语法是T<类>::iterator 迭代器指针名字 =
begin()这个接口返回一个指向容器第一个元素的迭代器。end()这个接口返回一个指向容器“尾后”位置的迭代器。注意,这不是容器的最后一个元素,而是最后一个元素再之后的位置。对于空容器,begin() 返回的迭代器与 end() 返回的迭代器是相等的。

下面是对vector、map和set使用迭代器进行遍历的示例代码:

(1)对vector的遍历

#include <iostream>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用迭代器遍历vectorfor (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用基于范围的for循环遍历vector(C++11及以后)for (int val : vec) {std::cout << val << " ";}std::cout << std::endl;return 0;
}

(2)对map的遍历

#include <iostream>
#include <map>int main() {std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"cherry", 3}};// 使用迭代器遍历mapfor (std::map<std::string, int>::iterator it = myMap.begin(); it != myMap.end(); ++it) {std::cout << it->first << ": " << it->second << std::endl;}// 使用基于范围的for循环遍历map(C++11及以后)for (const auto& kv : myMap) {std::cout << kv.first << ": " << kv.second << std::endl;}return 0;
}

(3)对set的遍历

#include <iostream>
#include <set>int main() {std::set<int> mySet = {1, 3, 5, 7, 9};// 使用迭代器遍历setfor (std::set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 使用基于范围的for循环遍历set(C++11及以后)for (int val : mySet) {std::cout << val << " ";}std::cout << std::endl;return 0;
}

在上面的代码中,可以看到对于vector、map和set,我们都可以使用传统的迭代器进行遍历,也可以使用C++11及以后版本的基于范围的for循环进行遍历。基于范围的for循环更加简洁,易于理解。但需要注意的是,基于范围的for循环在遍历map时,返回的是键值对(key-value pair),而不是单独的键或值。
注意map和set不支持用数组符号[]来遍历和索引。

4、仿函数

仿函数是行为类似于函数的对象。它们可以像函数一样被调用,并可以作为算法的参数,以定制算法的行为,一般配合 <algorithm> 使用。例如,std::less<T>是一个仿函数,用于比较两个对象是否一个小于另一个。

#include <vector>  
#include <algorithm>  
#include <iostream>  struct IsEven {  bool operator()(int n) const {  return n % 2 == 0;  }  
};  int main() {  std::vector<int> vec = {1, 2, 3, 4, 5};  vec.erase(std::remove_if(vec.begin(), vec.end(), IsEven()), vec.end());  for (const auto& element : vec) {  std::cout << element << " ";  }  return 0;  
}

在这个例子中,我们定义了一个仿函数IsEven,它接受一个整数并检查它是否为偶数。然后,我们使用std::remove_if算法和IsEven仿函数来移除vec中所有的偶数。

5、适配器

适配器用于修改容器或迭代器的接口,以提供不同的功能。例如,std::stack和std::queue就是基于std::dequestd::list等容器的适配器,它们提供了栈和队列的接口。

#include <stack>  
#include <iostream>  int main() {  std::stack<int> stk;  stk.push(1);  stk.push(2);  stk.push(3);  while (!stk.empty()) {  std::cout << stk.top() << " ";  stk.pop();  }  return 0;  
}

在这个例子中,我们使用了std::stack适配器来创建一个栈,并使用其提供的push、pop和top等方法来操作栈。

6、空间配置器

空间配置器负责内存的分配和释放。在STL中,它通常被封装起来,不需要直接操作。空间配置器允许STL库更高效地管理内存,特别是在大量小对象的情况下。

总结

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

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

相关文章

腾讯云4核8G12M云服务器一年646元,送3个月时长

2024年腾讯云4核8G服务器租用优惠价格&#xff1a;轻量应用服务器4核8G12M带宽646元15个月&#xff0c;CVM云服务器S5实例优惠价格1437.24元买一年送3个月&#xff0c;腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器优惠价格 轻…

《每天十分钟》-红宝书第4版-对象、类与面向对象编程(六)

盗用构造函数 上节提到原型包含引用值导致的继承问题&#xff0c;为了解决这种问题&#xff0c;一种叫作“盗用构造函数”&#xff08;constructor stealing&#xff09;的技术在开发社区流行起来&#xff08;这种技术有时也称作“对象伪装”或“经典继承”&#xff09;。基本…

若依 3.8.7版本springboot前后端分离 整合mabatis plus

1.去掉mybatis 这一步我没有操作&#xff0c;看别人的博客有说不去掉可能冲突&#xff0c;也可能不冲突&#xff0c;我试下来就没去掉如需要去除&#xff0c;到总的pom.xml中properties标签下的<mybatis-spring-boot.version>x.x.x</mybatis-spring-boot.version>…

C++ pdf 打印 插入图片

一&#xff1a;使用PODOFO给PDF插入图片&#xff1a; #include <podofo.h> int main() { PoDoFo::PdfMemDocument pdfDocument; PoDoFo::PdfPage* page; PoDoFo::PdfImage image; PoDoFo::PdfVecObjects* vec_objects; PoDoFo::PdfRect rect; …

Kotlin by关键字

委托的概念 委托是一种设计模式,它的基本概念是:操作对象自己不会去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理。 class NewList<out T>(private val list: MutableList<T>) {fun isEmpty() = list.isEmpty()fun add(item: @UnsafeVariance T) = l…

iPad Pro安装Code APP结合内网穿透实现公网SSH远程连接服务器云开发

文章目录 1. 在iPad下载Code APP2.安装cpolar内网穿透2.1 cpolar 安装2.2 创建TCP隧道 3. iPad远程vscode4. 配置固定TCP端口地址4.1 保留固定TCP地址4.2 配置固定的TCP端口地址4.3 使用固定TCP地址远程vscode 本文主要介绍开源iPad应用IDE Code App 如何下载安装&#xff0c;并…

零基础Web3入门到精通

Web3 是互联网的下一代&#xff0c;它将使人们能够拥有自己的数据并控制自己的在线体验。Web3 基于区块链技术&#xff0c;该技术为安全、透明和可信的交易提供支持。 现在的web已被成为传统互联网了&#xff0c;那么如何抓住下一代互联网的红利呢&#xff0c;有没有想一起学习…

react 简单的demo

实现些简单的deomo 显示时间 自定义hooks 使用定时器、生命周期、通过状态渲染更新 // hooks 文件 import { useEffect, useState } from reactfunction getDate() {let date new Date();let year date.getFullYear()let hour date.getHours();let minutes date.getMinut…

爬虫requests.get中的参数

requests.get 是 Python 中 requests 库的一个方法&#xff0c;用于发送 GET 请求。它有许多参数可以配置&#xff0c;以下是一些常见的参数&#xff1a; url&#xff1a;指定要发送 GET 请求的 URL。params&#xff1a;可选参数&#xff0c;用于向请求添加 URL 参数。data&…

多线程基础:线程创建、同步与通信——学习指南

多线程基础&#xff1a;线程创建、同步与通信——学习指南 文章目录 多线程基础&#xff1a;线程创建、同步与通信——学习指南前言一、线程创建1、原理2、案例3、使用场景推荐 二、线程同步1、原理2、案例1&#xff09;synchronized关键字1.1&#xff09;修饰实例方法&#xf…

qt-C++笔记之QSpinBox控件

qt-C笔记之QSpinBox控件 code review! 文章目录 qt-C笔记之QSpinBox控件1.运行2.main.cpp3.main.pro4.《Qt6 C开发指南》&#xff1a;4.4 QSpinBox 和QDoubleSpinBox 1.运行 2.main.cpp #include <QApplication> #include <QSpinBox> #include <QPushButton&g…

Vue3 实现基于token 用户登录

前后端分离情况下&#xff0c;实现的大致思路 1 第一次登录的时候&#xff0c;前端调用后端的登录接口&#xff0c;发送用户名与密码 2 后端收到请求&#xff0c;验证用户名和密码&#xff0c;验证成功 给前端返回一个token 3 前段拿到token 将token 存储进localStorage 和…

electron打包桌面版.exe之vue项目踩坑(vue3+electron 解决打包后首页打开空白,打包后路由不跳转及请求不到后端数据等问题)

vue项目https://www.qingplus.cn/components-web/index打包桌面版问题集合 一、静态资源加载问题 npm run electron_dev桌面版运行后页面空白&#xff0c;内容未加载。 填坑&#xff1a; 打包配置要用相对路径 vite.config.ts文件中的base要改成./&#xff0c;之前加了项目…

golang 和java对比

Go(也称为 Golang)和 Java 是两种流行的编程语言,它们在某些方面有相似之处,但在其他方面又有很大的区别。以下是它们之间的对比: 性能和并发性 Go:Go 是一种编译型语言,以其出色的并发性能而闻名。它具有轻量级的协程(goroutines)和通道(channels),使得编写并发代…

2024.3.27力扣(1200-1400)刷题记录

一、2215. 找出两数组的不同 1.排序双指针。我以为遍历时复很高&#xff0c;所以用的双指针。 class Solution:def findDifference(self, nums1: List[int], nums2: List[int]) -> List[List[int]]:#排序双指针nums1.sort()nums2.sort()ans [[],[]]a,b,n1,n2 0,0,len(nu…

软件接口安全设计规范及审计要点

1.token授权安全设计 2.https传输加密 3.接口调用安全设计 4.日志审计里监控 5.开发测试环境隔离&#xff0c;脱敏处理 6.数据库运维监控审计 项目管理全套资料获取&#xff1a;软件开发全套资料_数字中台建设指南-CSDN博客

Qt实现TFTP Server和 TFTP Client(四)

3.3 Server Server包括下面3个类&#xff1a; ServerSocketTFtpServerTFtpServerWidget 3.3.1 ServerSocket ServerSocket从BaseUdp派生实现write接口. 3.3.1.1 ServerSocket定义 class QUdpSocket; class ServerSocket : public BaseUdp { public:ServerSocket(QUdpSock…

Java 学习和实践笔记(49):用javabean和一维数组的方式来存储表格数据

还是存储下面这个表格的数据&#xff0c;但使用另一种方法来做。 用javabean和一维数组的方法来做&#xff0c;示例代码如下&#xff1a; /*先创建一个类&#xff0c;其实就是创建好一个只有各属性列的空表格*/ class Employees {private int id;private String name;private …

[2021]Zookeeper getAcl命令未授权访问漏洞概述与解决

今天在漏洞扫描的时候蹦出来一个zookeeper的漏洞问题&#xff0c;即使是非zookeeper的节点&#xff0c;或者是非集群内部节点&#xff0c;也可以通过nc扫描2181端口&#xff0c;获取极多的zk信息。关于漏洞的详细描述参考apache zookeeper官方概述&#xff1a;CVE-2018-8012: A…

Self-Consistency Improves Chain of Thought Reasoning in Language Models阅读笔记

论文链接&#xff1a;https://arxiv.org/pdf/2203.11171.pdf 又到了读论文的时间&#xff0c;内心有点疲惫。这几天还是在看CoT的文章&#xff0c;今天这篇是讲如何利用self-consistency&#xff08;自我一致性&#xff09;来改进大语言模型的思维链推理过程。什么是self-cons…