STL容器(持续更新中)

news2024/11/18 22:25:40

一、string类

1. 构造函数

常用的构造函数如下。

构造函数原型含义
string()默认构造函数。创建一个默认string对象,长度为0
string(const string &s)拷贝构造函数。用一个string对象初始化另一个string对象
string(const char *s)用字符串常量构建string对象
string(size_n n, ch ar c)构造一个包含n个元素的string对象,其中每个字符都被初始化为字符c

字符串常量,也就是C-风格的字符串,例如char str[] = "hello"
string类虽然看起来使用方法与C中的字符串数组差不多,但它并不是基于char类型实现的,而是基于模板类basic_string<char>的一个typedef。

#include <string>
string str;
string str1("hello world");
string str2(str1);
string str3(3, 'a');	// string对象为3个字符'a'

2. 运算符重载

string类中重载了一些运算符,使字符串操作更方便。

重载运算符含义
>>cin字符串输入
<<cout字符串输出
=将一个字符串赋给另一个字符串,可以附加字符串常量、单个char字符或string对象
+将两个字符串连在一起,操作对象可以是字符串常量、单个char字符或string对象
+=将一个字符串附加到另一个字符串后面,可以附加字符串常量、单个char字符或string对象
[]访问字符串中的各个字符
> >= < <= == !=比较字符串的大小,比较对象可以是string类或字符串常量

3. 常见成员函数

#include <string>
string str;

1. 获取字符串的长度
int len1 = str.length()
int len2 = str.size()
length()来自较早的string类,size()成员为STL兼容性添加的

2. 在字符串中搜索指定的字符或子字符串
函数原型:size_type find(const string & str, size_type pos = 0)const
从字符串的迫使、位置开始,查找字符串str
如果找到,则返回该子字符串首次出现时首个字符的索引;否则,返回string::npos
第一个参数也可以是char型(单个字符)或const char *型(字符串常量)

3. 容量操作
返回分配给字符串的内存块的大小:int cap = str.capacity()
规定请求内存块的最小长度:str.reserve(10)

4. 类型转换
将string字符串转换成c风格的字符串常量:const char *s = str.c_str()

npos是string类的静态成员,它的值是string对象能存储的最大字符数。由于索引从0开始,所以它比最大的索引值大1,因此可以使用它来表示没有查找到字符或字符串。

字符串在内存中占用一段连续的地址空间。如果进行将一个字符串连接到另一个字符串末尾的操作,则占用的空间变大,但相邻的内存可能已经被占用了,因此,需要分配一块新的连续内存块给连接后的字符串,字符串的内容复制到新的内存单元中。如果大量执行这样的操作,效率将非常低。因此,很多C++实现分配一个比实际字符串大的内存块,满足扩充字符串长度的需求。如果字符串长度依旧超出原有的范围,则程序将分配一个大小为原来两倍的新内存块,以提供足够大的空间。

举个例子

string small = "bit";
cout << small.capacity() << endl; // 输出15
small.reserve(50);
cout << small.capacity() << endl; // 输出63

二、标准库模板

1. 迭代器

所谓的迭代器,是一个广义指针。迭代器能够为STL的各种不同的容器类提供统一处理的接口,这些类通常都是简单指针无法处理的。每个容器类都定义了一个合适的迭代器,该迭代器的类型是一个名为iterator的typedef,其作用域为整个类。例如,声明一个double类型的vector容器的代码如下。

vector<double>::iterator pd;

2. STL通用方法

指向T的迭代器类型:X::iterator
T的类型:X::value_type
返回容器中元素的个数:a.size()
交换a和b的内容:a.swap(b)
返回指向容器中第一个元素的迭代器:a.begin()
返回指向容器超过容器尾的迭代器:a.end()
比较a和b,需要满足a和b长度相同,且每个元素都相等:a == b
比较a和b,不相等情况:a != b

3. vector矢量

传统的数组array是一块连续、固定的空间,并不能自由地改变array的大小,也就难以在数组中插入、删除元素。为了解决这个问题,C++定义了vector容器。

vector所采用的数据结构是线性连续空间,但是允许动态改变空间地大小。如果要换大一点或者小一点的空间,首先配置一块新的空间,然后将旧空间的数据拷贝到新空间,再释放原来的空间。

为了降低空间配置时的速度成本,vector实际配置的大小可能比用户实际需求大一些,以备将来可能的扩充,这边是容量(capacity)的概念。换句话说,一个vector的容量永远大于或等于其大小,一旦容量等于大小,便是满载,如果再有新增元素,整个vector容器就要在内存中再寻找一块满足容量大小地新居所,并将所有数据拷贝过去。

动态增加大小并不是在原空间之后续直接接新空间,因为无法保证原空间之后的空间没有被其他数据占用。因此找更大的内存空间,然后将原数据拷贝新空间,释放原空间。通常会新分配的空间是原空间大小的两倍。因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了。

因为vector维护的是一个连续空间,因此支持随机存取,提供随机访问迭代器(Random Access Iterators)。vector迭代器的功能可以完全覆盖普通指针的各种操作,如operator*, operator->, operator++, operator–, operator+, operator-, operator+=, operator-=,这些运算符的使用方式与普通指针完全相同。

创建vector类对象。

#include <vector>
创建vector对象,一维
不指定大小:vector<int> vec;
指定大小为5:vector<int> vec(5);

创建vector对象,二维
不指定大小:vector<vector<int>> vec;
指定大小,55列:
vector<int> temp(5);
vector<vector<int>> vec(5, temp));

vector类的操作。

#include <vector>
vector<int> vec;

容量操作:
获取数据个数:int size = vec.size()
获取容量大小:int cap = vec.capacity()
判断是否为空:vec.empty()
改变vector的size:vec.resize()
改变vector的capacity:vec.reserve()

增删查改:
int a;
int pos;
尾插:vec.push_back(a)
尾删:a = vec.pop_back()
查找:find
在pos之前插入元素a:vec.insert(pos, a);
删除pos位置的元素:vec.erase(pos);

vector的非成员函数。

对容器中的某一段元素进行遍历:for_each(起始位置,结束位置,函数指针)
例如
vector<Review>::iterator pr;
for (pr = books.begin(); pr != books.end(); pr++)
	ShowReview(*pr);
改写成for_each函数为
for_each(books.begin(), books.end(), ShowReview);

随机排列指定区间内的元素:Random_shuffle(起始位置,结束位置)
例如Random_shuffle(books.begin(), books.end());

对指定区间内的元素进行排序:sort(起始位置,结束位置)
如果容器元素是用户自定义的对象,则必须对运算符<进行重定义operator<()

4. deque双端队列

vector容器是单向开口的连续内存空间,允许在尾部插入新元素,尽管vector容器也可以在头部或中间插入元素,但效率极低,因为需要挨个向后面挪动元素。

deque容器则是一种双向开口的连续线性空间,头尾两端都可以做元素插入和删除操作。deque容器在逻辑空间上看是连续的,但实际上物理空间并不连续。每段数据空间内部是连续的,而每段数据空间之间则不一定连续。

deque由若干段的缓冲区构成,缓冲区中存放真实数据,同时使用一个中控器,维护每段缓冲区的地址。中控器是一种map(注意,不是STL的map容器),是一小块连续空间,其中每个元素(此处称为一个节点,node)都是指针,指向另一段(较大的)连续线性空间,称为缓冲区。缓冲区才是deque的储存空间主体。如下图所示。
deque的物理结构
deque除了维护一个指向map的指针外,还维护start、finish两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素(的下一位置)。此外,也必须记住目前的map大小,因为一旦map的所提供的空间不足,它将需要重新配置一个更大的空间,依然是经过三个步骤:配置更大的、拷贝原来的、释放原空间。

deque容器和vector容器的差异:

  1. deque能够在在常数项时间内在头部进行插入和删除操作,vector头插需要挨个挪动后面的元素。
  2. 在于deque没有容量的概念,因为它以分段的连续空间组合而成,随时可以增加一段新的空间并链接起来。deque不需要像vector那样预留一部分空间来减少重新分配内存并拷贝数据的次数。
  3. deque容器也提供了随机访问迭代器,但是它的迭代器并不是普通的指针,因此也比vector的迭代器实现起来更复杂。因此,除非有必要,我们应该尽可能的使用vector,而不是deque。

deque的常用操作函数如下。

#include <deque>
deque<int> elem;

两端插入删除:
push_back(elem);//在容器尾部添加一个数据
push_front(elem);//在容器头部插入一个数据
pop_back();//删除容器最后一个数据
pop_front();//删除容器的第一个数据

指定位置操作:
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
clear();//清空容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置
erase(pos);//删除pos位置的数据,返回下一个数据的位置

5. stack栈

栈是一种先进后出的数据结构,stack容器的底层实现是deque,stack没有迭代器。

#include <stack>
stack<int> st;
int a;
把元素a入栈:st.push(a)
栈顶元素出栈(没有返回值):st.pop()
返回栈顶元素(栈顶元素不出栈):a = st.top()
判断栈是否为空(为空则返回true):st.empty()

6. queue队列

队列是一种先进先出的数据结构,queue容器的底层实现是deque,queue没有迭代器。

#include <queue>
queue<int> q;
int a;
在队尾添加a元素:q.push(a)
移除队头元素(没有返回值):q.pop()
返回队头元素(队头元素不出队):a = q.front()
返回队尾元素(队尾元素不出队):a = q.back()
判断队列是否为空(为空则返回true):q.empty()

7. list双向循环链表

list的数据结构是双向循环链表,在逻辑空间上是连续的,但在物理空间上是非连续、非顺序的。它可以在常数时间内完成元素的插入和删除,但不支持随机访问,

list容器的迭代器是一种双向迭代器(Bidirectional Iterator),有能力进行正确的递增、递减、取值、成员存取操作:递增时指向下一个节点,递减时指向上一个节点,取值时取的是节点的数据值,成员取用时取的是节点的成员。

list的元素插入操作和删除操作都不会造成原有list迭代器的失效。这在vector是不成立的,因为vector的插入操作可能造成记忆体重新配置,导致原有的迭代器全部失效,但list不会。

list的常用操作函数如下。

#include <list>
list<int> l;
int a;
在链表头添加a元素:l.push_front(a)
从链表头移除元素(没有返回值):l.pop_front()
在链表尾添加a元素:l.push_back(a)
从链表尾移除元素(没有返回值):l.pop_back()

insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值
insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
clear();//清空容器的所有数据
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置
erase(pos);//删除pos位置的数据,返回下一个数据的位置

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

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

相关文章

Linux系统编程(vfork和fork)

文章目录 前言一、vfork讲解二、vfork使用三、exit和_exit1.exit和_exit对比2.在vfork中的使用 四、vfork和fork区别总结 前言 本篇文章讲解vfork和fork创建进程的区别。 一、vfork讲解 vfork 是一个在类Unix操作系统中的系统调用&#xff0c;它创建一个新进程&#xff0c;且…

欠拟合、过拟合、正则化、学习曲线

1.欠拟合、过拟合、正则化、学习曲线 1.1 欠拟合、过拟合 欠拟合&#xff1a;模型相对于要解决的问题来说太简单了&#xff0c;模型并没有拟合训练数据的状态 过拟合&#xff1a;模型相对于要解决的问题来说太复杂了&#xff0c;模型只能拟合训练数据的状态 下图来自&#x…

第41步 深度学习图像识别:Efficientnet建模(Tensorflow)

一、写在前面 &#xff08;1&#xff09;Efficientnet EfficientNet是Google在2019年提出的一种新的卷积神经网络架构&#xff0c;主要目标是提高模型的效率&#xff0c;即在保持或提高模型性能的同时&#xff0c;尽可能地降低模型的复杂性和计算需求。 EfficientNet的关键思…

【MySQL】表的内外连接

目录 一、内连接&#xff08;表1 inner join 表2 on&#xff09; 1、显示SMITH的名字和部门名称 二、外连接 1、左外连接&#xff08;表名1 left join 表名2 on&#xff09; 1.1查询所有学生的成绩&#xff0c;如果这个学生没有成绩&#xff0c;也要将学生的个人信息显示出…

2022(一等奖)D775北部湾红树林生理结构参数对水位变化的响应特征研究

作品介绍 1 应用背景 红树林作为全球生产力最高的生态系统之一&#xff0c;是生长在热带、亚热带海湾的一种特殊的木本植物群落。它由于其独特的海陆过渡特性&#xff0c;在维持滨海生态稳定、促进海陆能量循环中起着重要作用。同时&#xff0c;红树林可以吸附温室气体&#x…

第十二章 EfficientNetv2网络详解

系列文章目录 第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解 第四章 ResNet网络详解 第五章 ResNeXt网络详解 第六章 MobileNetv1网络详解 第七章 MobileNetv2网络详解 第八章 MobileNetv3网络详解 第九章 ShuffleNetv1网络详解 第十章…

Python爬取数据并进行数据CRUD的Web可视化项目

项目内容简介 爬取网站https://book.douban.com/top250上面的Top250数据,然后将数据保存到Mysql数据库中,最后这些数据记录以Web的方式进行展示,并实现对这些数据记录的CRUD(增删改查)! 项目实现简介 对豆瓣网站的爬虫的实现。 见项目中的爬取豆瓣Top250脚本(beautifulSoup).…

Linux下MySQL的安装与使用

文章目录 安装前说明Linux系统及工具的准备查看是否安装过MySQLMySQL的卸载 MySQL的Linux版安装下载MySQL指定版本CentOS7下检查MySQL依赖CentOS7下MySQL安装过程 查看MySQL版本服务的初始化启动MySQL&#xff0c;查看状态查看MySQL服务是否自启动 MySQL登录设置远程登录 安装前…

【计算机组成原理】输入输出系统

目录 一、外部设备概述 二、输入输出接口 三、主机与外设交换信息的方式 四、中断系统 五、中断请求 六、中断响应 七、中断服务 一、外部设备概述 外部设备在计算机系统中的作用&#xff1a; 人机对话的重要设备&#xff08;交互&#xff09;完成数据媒体变换的设别&…

chatgpt赋能python:Python等待一秒-程序员必知的等待操作

Python等待一秒 - 程序员必知的等待操作 时间是宝贵的资源&#xff0c;你可能会需要让你的Python程序等待一段时间才能继续执行。在这篇文章中&#xff0c;我们将学习如何使用Python等待一秒&#xff0c;包括为什么需要等待&#xff0c;以及在Python中如何等待。 为什么需要等…

前端web入门-CSS-day07

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 定位 相对定位 绝对定位 定位居中 固定定位 堆叠层级 z-index 定位-总结 高级技巧 CSS 精灵 字…

QT(一) 安装 QT(二)GUI程序设计基础

第一章 &#xff1a; Qt 安装 下载地址安装 打开 cmd 运行镜像 &#xff1a; qt-unified-windows-x64-4.6.0-online.exe --mirror https://mirrors.aliyun.com/qt Hello 因为是qmake 所以是.proCtrl R 直接运行 第二章 GUI程序设计基础 main文件 *.ui : 有UI设计器自动生成…

操作系统02-OS结构

目录 一、概述 二、内容 三、总结 一、概述 操作系统以服务的形式向程序和用户提供执行程序的基本服务&#xff0c;包括用户界面、程序执行、IO操作、文件系统操作、通讯、错误监测等。 二、内容 2.1 OS服务和接口 1 操作系统服务 2 操作系统程序接口&#xff1a;系统调…

阿里架构师分享分布式架构笔记文档:Nginx+Redis+ZK+Kafka+MQ等

Nginx Nginx 是一款非常优秀的开源软件&#xff0c;工作需要&#xff0c;研究了很久一段时间的 Nginx 源码&#xff0c;在研究学习的过程中收益颇多。作为高性能服务器的代表&#xff0c;为了追求极致的高性能&#xff0c;在许多方面&#xff0c;Nginx 的源码实现都可以称得上…

Reqable HTTP一站式开发+调试工具(小黄鸟作者另一力作、小黄鸟完美替代品)

本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删!Reqable HTTP一站式开发+调试工具(小黄鸟作者另一力作、小黄鸟替代品) 环境 win10pixel4Android13概览 …

JS将PDF转图片,pdfjs的使用

Hi I’m Shendi 最近做转换工具&#xff0c;需要将pdf转图片&#xff0c;这里记录下来 JS将PDF转图片&#xff0c;pdfjs的使用 简介 A general-purpose, web standards-based platform for parsing and rendering PDFs. 一个通用的、基于web标准的平台&#xff0c;用于解析和…

word公式mathtype公式

行间公式&#xff1a; 直接点“有编号” 内联公式&#xff1a; 直接点“内联” 交叉引用&#xff1a; 插入引用&#xff0c;双击编号 行内公式大小不统一&#xff0c;公式的代码可能上漂 解决方案&#xff1a;法一&#xff1a;切换Tex&#xff0c;再次切换过来。 法二&…

ElasticSearch的核心概念简单描述

我正在参加「掘金启航计划」 ES核心概念 ES是面向文档,下面表格是和关系型数据库的对比,一切都是JSON 关系数据库(Mysql)ES数据库(database)索引(indices) 和数据库一样表(tables)types 慢慢会被弃用 7.0已经过时 8.0会彻底废弃行(rows)documents (数据)文档字段(columns)fi…

简单图论+二分搜索:环境治理

题目描述 LQ 国拥有 n 个城市, 从 0 到 n−1 编号, 这 n 个城市两两之间都有且仅有 一条双向道路连接, 这意味着任意两个城市之间都是可达的。每条道路都有一 个属性 D, 表示这条道路的灰尘度。当从一个城市 A 前往另一个城市 B 时, 可 能存在多条路线, 每条路线的灰尘度定义为…

前端项目规范化:手把手教你使用prettier和pre-commit(git hook或者husky)优化规范项目代码

如何在提交代码之前&#xff0c;进行代码格式化检查&#xff0c;保证每个成员的代码都是同一个风格呢&#xff1f; 最简单的两种方式&#xff1a; 使用 prettier git pre-commit 使用 prettier husky(原理和第一种一模一样哦) 名词简介 git hooks 下图为git hooks的官方…