C++专题--标准模板库STL

c++专题-标准模板库STL

  • 1   标准模板库概述
  • 2   序列式容器
    •   2.1 vector 容器
    •   2.2 deque 容器
    •   2.3 list 容器
  • 3   关联式容器
  • 4   无序关联容器
  • 5   容器适配器
    •   5.1 STL容器适配器的种类
    •   5.2 stack容器适配器
    •   5.3 queue容器适配器
    •   5.3 priority_queue容器适配器

1   标准模板库概述

STL,英文全称 standard template library,中文可译为标准模板库或者泛型库,其包含有大量的模板类和模板函数,是 C++ 提供的一个基础模板的集合,用于完成诸如输入/输出、数学计算等功能

容器的分类

在这里插入图片描述

2   序列式容器

  2.1 vector 容器

  2.2 deque 容器

  2.3 list 容器

STL list 容器,又称双向链表容器,即该容器的底层是以双向链表的形式实现的。这意味着,list 容器中的元素可以分散存储在内存空间里,而不是必须存储在一整块连续的内存空间中 st 容器中各个元素的前后顺序是靠指针来维系的,每个元素都配备了 2 个指针,分别指向它的前一个元素和后一个元素。其中第一个元素的前向指针总为 null,因为它前面没有元素;同样,尾部元素的后向指针也总为 null。

基于这样的存储结构,list 容器具有一些其它容器(array、vector 和 deque)所不具备的优势,即它可以在序列已知的任何位置快速插入或删除元素(时间复杂度为O(1))。并且在 list 容器中移动元素,也比其它容器的效率高

  1. list 容器的创建
/**** list 相关的方法测试* @brief AdapterTest::listTest* @return*/
int32 AdapterTest::listTest()
{// 创建一个没有任何元素的空list容器std::list<int32> li1;// 创建一个包含n个元素的list容器std::list<int32> li2(10);// 创建一个包含n个元素的list容器,并为每个元素指定初始值std::list<int32> li3(10,8);// 在已有 list 容器的情况下,通过拷贝该容器可以创建新的list容器std::list<int32> li4(li3);// 采用此方式,必须保证新旧容器存储的元素类型一致std::list<int32> testList;for(int i = 0; i < 100;i+=10){if ((i & 1) == 0){testList.push_back(i);}}cout << "size : " << testList.size() << endl;// begin()  返回指向容器中第一个元素的双向迭代器// end()    返回指向容器中最后一个元素所在位置的下一个位置的双向迭代器std::list<int32>::iterator iter = testList.begin();// 1.遍历cout << "------using iterator to travelsal list begin------" << endl;for(;iter != testList.end();++iter){cout << *iter << " ";}cout << endl;cout << "------using iterator to travelsal list end------" << endl;// const_iterator cbegin() 也可以换成 begin()  cend() 也可以换成 end()std::list<int32>::const_iterator citer = testList.cbegin();cout << "------using const_iterator to travelsal list begin------" << endl;for(;citer != testList.cend();++citer){cout << *citer << " ";}cout << endl;cout << "------using const_iterator to travelsal list end------" << endl;// 反向迭代器 rbegin() rend()cout << "------using reverse_iterator to travelsal list begin------" << endl;//  std::list<int32>::const_reverse_iterator 使用这个也可以std::list<int32>::reverse_iterator riter = testList.rbegin();for(;riter != testList.rend();++ riter){cout << *riter << " ";}cout << endl;cout << "------using reverse_iterator to travelsal list end------" << endl;cout << "empty : " << testList.empty() << endl;cout << "size : " << testList.size() << endl;// 返回第一个元素的引用cout << "front : " << testList.front() << endl;// 返回最后一个元素的引用cout << "back : " << testList.back() << endl;// 在容器尾部插入一个元素testList.push_back(766);cout << "back : " << testList.back() << endl;// 删除容器尾部的一个元素 无返回值testList.pop_back();// 在容器中的指定位置插入元素。该函数和insert()功能相同,但效率更高testList.emplace(testList.end(),800);cout << "back : " << testList.back() << endl;// insert() 在容器中的指定位置插入元素testList.insert(testList.begin(),900);cout << "front : " << testList.front() << endl;// 删除指定区间的元素 返回指向下一个元素的迭代器iter = testList.erase(testList.begin());cout << *iter << endl;
}

  1. list 遍历删除元素
int32 AdapterTest::listRemoveTest()
{std::list<int32> testList;for(int i = 0;i<100;++i){testList.push_back(i);}std::list<int32>::const_iterator iter = testList.begin();for (;iter != testList.end();++iter){cout << *iter << " ";}cout << endl;for(iter = testList.begin();iter != testList.end();){if((*iter & 1) == 0){// 删除 iter 指向的元素 并返回指向下一个元素的迭代器iter = testList.erase(iter);} else {++iter;}}cout << "------------------------------" << endl;iter = testList.begin();for (;iter != testList.end();++iter){cout << *iter << " ";}cout << endl;
}

3   关联式容器

4   无序关联容器

5   容器适配器

  5.1 STL容器适配器的种类


公共的头文件部分commondef.h

#ifndef COMMONDEF_H
#define COMMONDEF_H
#include <iostream>
#include <array>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <map>
#include <utility> // pair 类模板定义在<utility>头文件中
#include <set>
#include <cstring>
#include <typeinfo>
#include <deque>
#include <list>
#include <forward_list>#define TABLE_NUM 14
#define AISTD std::
#define TABLE_NAME_LEN 128
const char PATH_SEPARATOR = '/';
#define  DATE_CHANGE_NUM 1000000LL
#define BUFFER_SIZE 1024
#define LINE cout << "********************************************************" << endl;
#define LINEFEED cout << endl;
#define FUNCTION_BEGIN  \cout << __FILE__ << ":" <<  __LINE__ << ":" << __FUNCTION__ << " : begin >>> " << endl;
#define FUNCTION_END \cout << __FILE__ << ":" <<  __LINE__ << ":" << __FUNCTION__ << " : end >>> " << endl;typedef std::string aistring;
typedef int int32;
typedef long long int64;
typedef short int int16;
using namespace std;#endif // COMMONDEF_H

简单的理解容器适配器,其就是将不适用的序列式容器(包括 vector、deque 和 list)变得适用。容器适配器的底层实现和模板 A、B 的关系是完全相同的,即通过封装某个序列式容器,并重新组合该容器中包含的成员函数,使其满足某些特定场景的需要。

STL 提供了 3 种容器适配器,分别为 stack 栈适配器、queue 队列适配器以及 priority_queue 优先权队列适配器。其中,各适配器所使用的默认基础容器以及可供用户选择的基础容器

容器适配器基础容器筛选条件默认使用的基础容器
stack 基础容器需包含以下成员函数: empty()   size() back() push_back() pop_back() 满足条件的基础容器有 vector、deque、listdeque
queue 基础容器需包含以下成员函数: empty() size() front() back() push_back() pop_front() 满足条件的基础容器有 deque、listdeque
priority_queue 基础容器需包含以下成员函数: empty() size() front() push_back() pop_back() 满足条件的基础容器有vector、dequevector

  5.2 stack容器适配器

stack容器适配器的创建

/****  stack使用的基础容器有 :*      - vector*      - list*      - deque (默认)* @brief AdapterTest::stackTest* @return**/
int32 AdapterTest::stackTest()
{// 创建一个不包含任何元素的 stack 适配器,并采用默认的 deque 基础容器stack<int32> s1;// 使用基础容器list来初始化 stack 适配器,只要该容器的类型和 stack 底层使用的基础容器类型相同即可stack<int32,list<int32>> s2;for(int i = 0;i < 10;++i){// 压栈s1.push(i);}if(!s1.empty()){// 栈顶元素cout << "top : " << s1.top() << endl;// 栈中元素的个数cout << "size : " << s1.size() << endl;}while(!s1.empty()){std::cout << s1.top() << " ";s1.pop();}std::cout << endl;return 0;
}

  5.3 queue容器适配器

stack 栈容器适配器不同,queue 容器适配器有 2 个开口,其中一个开口专门用来输入数据,另一个专门用来输出数据

最先进入 queue 的元素,也可以最先从 queue 中出来,即用此容器适配器存储数据具有“先进先出(简称 “FIFO” )”的特点,因此 queue 又称为队列适配器。

queue适配器的创建及常用成员函数

int32 AdapterTest::queueTest()
{// 创建一个空的 queue 容器适配器,其底层使用的基础容器选择默认的 deque 容器queue<int32> q1;// 创建了一个使用 list 容器作为基础容器的空 queue 容器适配器queue<int32,list<int32>> q2;// 用基础容器来初始化 queue 容器适配器,只要该容器类型和 queue 底层使用的基础容器类型相同即可std::deque<int32> values{1,6,7,10,12};queue<int32> q3(values);/*** queue支持的成员函数* - empty()* - front() 返回queue中第一个元素的引用.如果queue是常量,就返回一个常引用;如果queue为空,返回值是未定义的* - back()  返回queue中最后一个元素的引用.如果queue是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的* - push()  在queue的尾部添加一个元素的副本.这是通过调用底层容器的成员函数push_back()来完成的.* - pop()   删除 queue 中的第一个元素*/cout << "empty : " << q3.empty() << endl;int32& val = q3.front();cout << "val : " << val << endl;val = q3.back();cout << "val : " << val << endl;q3.push(20);val = q3.back();cout << "val : " << val << endl;while (! q3.empty()){cout << "front ele " << q3.front() << endl;q3.pop();}return 0;
}

  5.3 priority_queue容器适配器

priority_queue 容器适配器模拟的也是队列这种存储结构,即使用此容器适配器存储元素只能“从一端进(称为队尾),从另一端出(称为队头)”,且每次只能访问 priority_queue 中位于队头的元素

但是,priority_queue 容器适配器中元素的存和取,遵循的并不是 “First in,First out”(先入先出)原则,而是"First in,Largest out"原则。直白的翻译,指的就是先进队列的元素并不一定先出队列,而是优先级最大的元素最先出队列

priority_queue 容器适配器为了保证每次从队头移除的都是当前优先级最高的元素,每当有新元素进入,它都会根据既定的排序规则找到优先级最高的元素,并将其移动到队列的队头;同样,当 priority_queue 从队头移除出一个元素之后,它也会再找到当前优先级最高的元素,并将其移动到队头

基于 priority_queue 的这种特性,因此该容器适配器有被称为优先级队列

template <typename T,typename Container=std::vector<T>,typename Compare=std::less<T> >
class priority_queue{//......
}

typename T:指定存储元素的具体类型;
typename Container:指定 priority_queue底层使用的基础容器,默认使用 vector 容器
typename Compare:指定容器中评定元素优先级所遵循的排序规则,默认使用std::less<T>按照元素值从大到小进行排序,还可以使用std::greater<T>按照元素值从小到大排序,但更多情况下是使用自定义的排序规则

  1.   priority_queue创建的几种方式

由于 priority_queue 容器适配器模板位于头文件中,并定义在 std 命名空间里,因此在试图创建该类型容器之前,程序中需包含以下 2 行代码:

#include <queue>
using namespace std;
/*** priority_queue 使用的基础容器*  - vector (默认)*  - dequeu* @brief AdapterTest::priorityQueueTest* @return*/
int32 AdapterTest::priorityQueueTest()
{// 创建一个空的priority_queue容器适配器,底层采用默认的vector容器,排序方式也采用默认的std::less<T>方法std::priority_queue<int32> pq;// 可以使用普通数组或其它容器中指定范围内的数据,对priority_queue容器适配器进行初始化:int values[]{20,30,90,17,23,45};//使用普通数组std::priority_queue<int32> q1(values,values+5);std::vector<int32> v1{100,78,32,87,49,23};//使用向量std::priority_queue<int32> q2(v1.begin(),v1.end());// 指定优先级队列的底层排序规则 小的排在前面std::priority_queue<int32,std::deque<int32>,std::greater<int32>> q3(v1.begin(),v1.end());/*** priority_queue提供的成员函数*     - empty()   如果 priority_queue 为空的话,返回 true;反之,返回 false*     - size()    返回 priority_queue 中存储元素的个数*     - top()     返回 priority_queue 中第一个元素的引用形式*     - push(const T& obj)*       根据既定的排序规则,将元素 obj 的副本存储到 priority_queue 中适当的位置。*     - push(T&& obj)*       根据既定的排序规则,将元素 obj 移动存储到 priority_queue 中适当的位置*     - pop()*       移除 priority_queue 容器适配器中第一个元素*     - swap(priority_queue<T>& other)*         将两个priority_queue容器适配器中的元素进行互换,*         需要注意的是,进行互换的2个priority_queue容器*         适配器中存储的元素类型以及底层采用的基础容器类型*         都必须相同*/cout << "size : " << q3.size() << endl;while (!q3.empty()){cout << q3.top() << " ";q3.pop();}cout << endl;cout << "---------------------q2---------------------" << endl;cout << "size : " << q2.size() << endl;while (!q2.empty()){cout << q2.top() << " ";q2.pop();}cout << endl;int32 nums[]{10,34,56,89,78,20};std::priority_queue<int32> q4(nums,nums+5);q2.swap(q4);cout << "---------------------q2---------------------" << endl;while (!q2.empty()){cout << q2.top() << " ";q2.pop();}cout << endl;return 0;
}
  1. priority_queue容器适配器实现自定义排序
      无论 priority_queue 中存储的是基础数据类型(int、double 等),还是 string 类对象或者自定义的类对象,都可以使用函数对象的方式自定义排序规则
template <typename T>
// 函数对象类
class IntegerComp
{
public:IntegerComp() {}//重载()bool operator()(const T& l,const T& r){return l < r;}
};

上面的 class关键字也可以使用 struct关键字替代

// 函数对象类
template <typename T>
struct IntegerComp
{
public:IntegerComp() {}//重载()bool operator()(const T& l,const T& r){return l > r;}
};

自定义优先级 coding

/***** 优先级队列自定义排序规则* @brief AdapterTest::priorityQueueCustomerTest* @return*/
int32 AdapterTest::priorityQueueCustomerTest()
{int values[]{10,6,23,78,87,90};// l < r 时升序// l > r 时降序std::priority_queue<int32,std::deque<int32>,IntegerComp<int32>> prioQueue(values,values + 6);cout << "------------prioQueue: ------------" << endl;while(! prioQueue.empty()){cout << prioQueue.top() << " ";prioQueue.pop();}cout << endl;
}

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

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

相关文章

【linux】安装pytorch3d

写在开头 不要看网上的博客安装&#xff0c;直接参考官方安装文档去安装。 坑 坑1&#xff1a;安装pytorch3d后torch.cuda用不了 使用下面的命令安装后 conda install pytorch3d会提示安装下面的包&#xff0c;注意pytorch和torchvision都是cpu版本的&#xff0c;这样就会…

如何让你的图片服务也有类似OSS的图片处理功能

原文链接 前言 有自己机房的公司一般都有一套存储系统用于存储公司的图片、视频、音频、文件等数据&#xff0c;常见的存储系统有以NAS、FASTDFS为代表的传统文件存储&#xff0c;和以Minio为代表的对象存储系统&#xff0c;随着云服务的兴起很多公司逐渐将数据迁移到以阿里云…

SQL Server2019安装后使用SQL Server身份验证登录失败

错误情况 今天在电脑安装SQL Server2019和SMMS&#xff0c;安装过程一切顺利&#xff0c;但是在使用SMMS连接数据库时出现了异常。使用"Window 身份验证"登录时正常&#xff0c;但是如果改为使用"SQL Server 身份验证"登录时却连接失败&#xff01; 解决方…

【LeetCode每日一题】——41.缺失的第一个正数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 哈希表 二【题目难度】 困难 三【题目编号】 41.缺失的第一个正数 四【题目描述】 给你一个…

MapStruct 中 Java Bean 映射代码生成器的基本使用

文章目录 一、简介&#xff1a;二、背景&#xff1a;三、相关概念&#xff1a;1、映射器&#xff08;Mapper&#xff09;&#xff1a;2、映射方法&#xff08;Mapping Method&#xff09;&#xff1a;3、常规映射方法&#xff08;Regular Mapping Method&#xff09;&#xff1…

前端开发:数组对象判断重复的方法详解

前言 在前端开发过程中,关于数据处理是非常常用的操作,尤其是通过算法处理从后端获取的数据甚为重要。而且在前端开发中,两大类型的数据处理是必备的:数组和对象。与其说是数据处理,不如说是数组和对象的处理。实际开发中,关于数组数据的处理所占比例更高,尤其是涉及到表…

新增守护进程管理、支持添加MySQL远程数据库,支持PHP版本切换,1Panel开源面板v1.5.0发布

2023年8月14日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.5.0版本。 在这个版本中&#xff0c;1Panel新增了守护进程管理功能&#xff1b;支持添加MySQL远程数据库&#xff1b;支持添加FTP/S和WebDAV的SFTP服务&#xff1b;支持PHP版本切换。此外&am…

字节原来这么容易进,是面试官放水,还是公司实在是太缺人?

本人211非科班&#xff0c;之前在字节和腾讯实习过&#xff0c;这次其实没抱着什么特别大的希望投递&#xff0c;没想到字节可以再给我一次机会&#xff0c;还是挺开心的。 本来以为有个机会就不错啦&#xff01;没想到能成功上岸&#xff0c;在这里要特别感谢帮我内推的同学&…

selenium自动化测试之搭建测试环境

自动化测试环境&#xff1a; Python3.7Selenium3.141谷歌浏览器76.0/火狐浏览器 1、安装Python并配置环境变量。 下载并安装&#xff1a;配置环境变量&#xff1a;C:\Python37;C:\Python37\Scripts; 2、安装Pycharm开发工具。 下载地址&#xff1a; 注意下载&#xff1a;Co…

数据库内日期类型数据大于小于条件查找注意事项

只传date格式的日期取查datetime的字段的话默认是 00:00:00 日期类型字符串需要使用 ’ ’ 单引号括住 使用大于小于条件查询某一天的日期数据 前后判断条件不能是同一天 一个例子 数据库内数据&#xff1a; 查询2023-08-14之后的数据&#xff1a; select * from tetst…

Debian10:安装PHPVirtualBox

PHPVirtualBox 是一个用 PHP 编写&#xff0c;用于管理 VirtualBox 的 Web 前端&#xff08;由AJAX实现&#xff09;。 参考文章&#xff1a;VirtualBoxPHPVirtualBox部署_骡子先生的博客-CSDN博客php virualbox,浏览器远程控制VBox 虚拟机phpVirtualBox_weixin_39815879的博客…

单源最短路

目录 Dijkstra求最短路 I Dijkstra求最短路 II&#xff08;堆优化版&#xff09; spfa求最短路 spfa判断负环 信使 香甜的黄油 最小花费 最优乘车 昂贵的聘礼 最重要的是问题的转化和抽象 把问题转化成最短路的模板 无负环 Dijkstra 迪杰斯特拉算法 采用的贪心的策略 每…