【C++】STL(1) - 序列容器

文章目录

  • 1. 一些概念
    • 1.1 STL容器类型
    • 1.2 补充
  • 2. vector
    • 2.1 基本用法
      • 2.1.1 创建
      • 2.1.2 访问
      • 2.1.3 增删改
      • 2.1.4 查找
      • 2.1.4 排序
      • 2.1.5 其他操作
    • 2.2 二维数组
    • 2.3 补充
  • 3. list
    • 3.1 forward_list:单链表
    • 3.2 list:双链表
  • 4. array
  • 5. deque
  • 6. 元组
    • 6.1 二元组pair
    • 6.2 多元组tuple
      • 6.2.1 创建和初始化
      • 6.2.2 tuple元素为引用类型时用例
      • 6.2.3 基本操作

1. 一些概念

1.1 STL容器类型

序列容器:线性数据结构容器。

  • 数组:vector(动态大小,随机访问,尾部高效插入删除)),array(固定大小,随机访问)。
  • 链表:forward_list(单链表),list(双链表)。
  • 双端队列:deque(动态大小,随机访问,头尾高效插入删除)。

关联容器:非线性数据结构容器。可分为有序关联容器和无序关联容器。

  • 有序关联容器:set(不重复元素的集合),multiset(可重复元素的集合),map(不重复key的字典),multimap(可重复key的字典)

  • 无序关联容器:unordered_set,unordered_multiset,unordered_map,unordered_multimap

适配器:序列容器和关联容器称为首类容器,适配器是基于首类容器进行封装出来的容器。stack,queue,priority_queue

1.2 补充

  • 近似容器(near container):基于指针的数组;bitset;valarray

  • tuple不属于STL容器。

2. vector

2.1 基本用法

2.1.1 创建

创建vector会先分配一定容量,插入时如果容量不够,则申请现有容量的2倍再执行插入操作

#include <vector>
vector < int > v0;				  // 初始大小为0
vector < int > v1(10);			  // 初始大小为10,默认元素值为0
vector < int > v2(10, 1);		  // 初始大小为10,指定初始值为1
vector < int > v3 = { 1, 2, 3 };  // 使用初始化列表初始化vector对象
vector < int > v4(v3);			  // 用一个vector初始化另一个vector// 基础信息:长度,容量,最大容量
cout << "size: " << vec.size() << endl;			// 数组长度
cout << "capacity: " << vec.capacity() << endl;	// 当前给数组分配的容量
cout << "max_size: " << vec.max_size() << endl; // 数组最大长度,固定/*
v0: size=0, capacity=0, max_size=4611686018427387903
v1: size=10, capacity=10, max_size=4611686018427387903
v2: size=10, capacity=10, max_size=4611686018427387903
v3: size=3, capacity=3, max_size=4611686018427387903
v4: size=3, capacity=3, max_size=4611686018427387903
*/v3.push_back(4);  // v3: size=4, capacity=3*2=6

2.1.2 访问

// 遍历所有元素1:下标法
vector<int> arr(10, 1)
for(auto i = 0; i <arr.size3(); ++i){cout << arr[i];
}// 遍历所有元素2:迭代器法
for(auto it = arr.begin(); it != arr.end(); it++){cout << *it;
}// 遍历所有元素3:采用输出迭代器
ostream_iterator<int> output( cout, " " );  // #include <iterator>
copy( arr.cbegin(), arr.cend(), output );  	// #include <algorithm>// 访问单个元素1:下标法
cout << arr[2];// 访问单个元素2:at()方法
cout << arr.at(2);// 访问单个元素3:迭代器
auto it = arr.begin();
cout << *(it + 2);// 访问单个元素:首元素
cout << arr.front();// 访问单个元素:尾元素
cout << arr.back()

2.1.3 增删改

// 插入:指定位置插入单个元素
vector<int> arr(3, 1);
vector<int> arr1(2, -1);
int pos = 1;
arr.insert(arr.begin() + pos, 0);		 			// arr = {1, 0, 1, 1}
// 插入:指定位置插入多个元素
arr.insert(arr.begin() + pos, 3, 2);				// arr = {1, 2, 2, 2, 0, 1, 1}
arr.insert(arr.begin(), arr1.begin(), arr1.end());	// arr = {-1, -1, 1, 2, 2, 2, 0, 1, 1}
arr.insert(arr.begin(), {3, 3});  					// arr = {3, 3, -1, -1, 1, 2, 2, 2, 0, 1, 1}
// 插入:尾部插入单个元素
arr.push_back( 4 );  								// arr = {3, 3, -1, -1, 1, 2, 2, 2, 0, 1, 1, 4}// 删除:指定位置删除单个元素
pos = 3;
arr.erase(arr.begin() + pos);						// arr = {3, 3, -1, 1, 2, 2, 2, 0, 1, 1, 4}
// 删除:指定位置删除多个元素
arr.erase(arr.begin() + pos, arr.begin() + pos + 2);// arr = {3, 3, -1, 2, 2, 0, 1, 1, 4}
// 删除:尾部删除单个元素
arr.pop_back();										// arr = {3, 3, -1, 2, 2, 0, 1, 1}// 修改
arr[2] = -2;										// arr = {3, 3, -2, 2, 2, 0, 1, 1, 4}

2.1.4 查找

// 使用algorithm库中的find函数
#include <algorithm>
using namespace std;vector<int> arr = {1, 2, 3, 4, 5};
auto it = find(arr.begin(), arr.end(), 3);
if(it != arr.end()){cout << "find elem: " << *it << endl;
} else {cout << "not found!" << endl;
}// 手动遍历找,略

2.1.4 排序

// 使用sort升序排序(基本数据类型)
vector<int> arr(10) = {7, 5, 3, 4, 1, 2, 6, 9, 8, 10};
sort(arr.begin(), arr.end());// 自定义排序:降序
bool compareDesc(int a, int b) {return a > b;
}
sort(arr.begin(), arr.end(), compareDesc);// 使用lambda表达式:降序
sort(arr.begin(), arr.end(), [](int a, int b) {return a > b;
});// 稳定排序
stable_sort(arr.begin(), arr.end());

2.1.5 其他操作

// 判断是否为空
if( arr.empty() ){cout << "arr is empty!" << endl;
}// vector对象的比较
vector < int > a1(7);
vector < int > a2(7);
if ( a1 == a2 )  // a != bcout << " vector a1 is eqaul vector a2";// 清空vector
arr.clear();			 // 会调用erase方法,size=0, capacity不变// 缩放vector
vector<int> arr(2, 1);  // size=2, capacity=2
arr.resize(5);			// 扩充时capactity不够,默认扩充元素为0:arr=[1,1,0,0,0], size=5, capacity=5
arr.resize(2);			// 缩小不改变capacity:arr=[1,1], size=2, capacity=5
arr.resize(3, 2);		// 扩充时capacity够,指定扩充元素为2:arr=[1,1,2], size=3, capacity=5
arr.shrink_to_fit();	// 将capacity值调整为 capacity = size = 3

2.2 二维数组

#include <vector>
const int rows = 5;
const int cols = 5;
vector<vector<int>> mat(rows, vector<int>(cols, 1));  // 全1的5×5矩阵for(size_t i=0; i<mat.size(); i++){for(size_t j =0; j<mat.size(); j++){cout << mat[i][j] << " ";}cout << endl;
}for(auto row = mat.begin(); row != mat.end(); row++){for(auto elem = row->begin(); elem != row->end(); elem++){cout << *elem << " ";}cout << endl;
}

2.3 补充

  • vector元素为指针时,erase函数会根据不同类型的指针采取不同的操作:如果元素是指向动态分配内存的指针,erase不删除动态内存;如果元素为unique_ptr,则erase会删除其指向的对象;如果元素为shared_ptr则erase不删除对象而将所指向对象的引用计数减1,引用计数为0才删除对象。
  • 相比于下标访问元素,调用at()方法访问元素可以使用捕获越界异常。STL常见的异常:out_of_range、invalid_argument、length_error、bad_alloc

3. list

3.1 forward_list:单链表

#include <forward_list>
forward_list<int> flist = {1, 3, 4};// 插入: 指定位置之后插入
flist.insert_after(flist.begin(), 2);  		// {1,2,3,4}// 插入:在头部插入
flist.push_front(0);  						// {0,1,2,3,4}// 在容器内生成元素,避免调用拷贝或者移动构造函数
flist.emplace_front(-2);  					// {-2,0,1,2,3,4}
flist.emplace_after(flist.begin(), -1);  	// {-2,-1,0,1,2,3,4}// 删除: 删除指定位置后的一个元素
flist.erase_after(flist.begin());			// {-2,0,1,2,3,4}// 删除:删除首元素
flist.pop_front();							// {0,1,2,3,4}// 查找:单链表只能顺序查找
int target = 3;
for(auto elem: flist){if( target == elem ){cout << "elem found!" << endl;    }
}// 获取列表长度
size_t len = distance(flist.begin(), flist.end());
cout << "len: " << len << endl;// 清空列表
flist.clear();

3.2 list:双链表

#include <list>
list<int> mylist0 = {1, 3, 4};
list<int> mylist1(3, 1);// 插入:在头部插入元素
mylist0.push_front(0);				// {0,1,3,4}
// 插入:在尾部插入元素
mylist0.push_back(5);    			// {0,1,3,4,5}
// 插入:在指定位置插入元素
mylist0.insert(mylist0.begin(), -1); // {-1,0,1,3,4,5}// 删除:删除首元素
mylist0.pop_front();				// {0,1,3,4,5}
// 删除:删除尾元素
mylist0.pop_back();					// {0,1,3,4}
// 删除:删除指定位置元素
mylist0.erase(mylist0.begin());		// {1,3,4}// 查找:链表只能顺序访问
int target = 3;
for(auto elem: mylist0){if( target == elem ){cout << "elem found!" << endl;    }
}// 清空list
mylist0.clear();

4. array

#include <array>array<int, 10> arr0;  // 使用未定义的默认值初始化
array<int, 10> arr1 = {1, 2, 3};  // 剩余元素用0填充;如果元素类型为类类型,则会调用默认构造函数 // 访问:下标
cout << arr1[0] << endl;
// 访问:at()方法
cout << arr1.at(1) << endl;
// 访问:迭代器
auto it = arr1.begin() + 2;
cout << *it << endl;// 获取数组大小
cout << "size: " << arr1.size() << endl;// 检查数组是否为空
if(arr1.empty()){cout << "arr1 is empty" << endl;
}// 交换数组
for(auto i = 0; i<arr0.size(); i++ ){arr0[i] = i;
}
arr0.swap(arr1);
/*
交换前:arr0=[0,1,2,3,4,5,6,7,8,9]; arr1=[1,2,3,0,0,0,0,0,0,0]
交换后:arr0=[1,2,3,0,0,0,0,0,0,0]; arr1=[0,1,2,3,4,5,6,7,8,9]
*/

5. deque

#include <deque>
deque<int> dq0(3, 1);
deque<int> dq1={1, 2, 3};// 访问:使用下标
cout << dq1[0] << ' ';
// 访问:使用at()方法
cout << dq1.at(1) << ' ';
// 访问:使用迭代器
auto it = dq1.begin() + 2;
cout << *it << endl;
// 访问:访问首元素
cout << dq1.front() << ' ';
// 访问:访问尾元素
cout << dq1.back() << ' ';// 插入:在指定位置插入元素
dq1.insert(dq1.begin()+1, 0);
// 插入:在头部插入元素
dq1.push_front(0);
// 插入:在尾部插入元素
dq1.push_back(4);// 删除:删除指定位置元素
dq1.erase(dq1.begin()+1);
// 删除:删除头部元素
dq1.pop_front();
// 删除:删除尾部元素
dq1.pop_back();// 遍历1
for(auto elem: dq1){cout << elem << ' ';
}
cout << endl;
// 遍历2
for(auto it=dq1.begin(); it!=dq1.end(); it++){cout << *it << ' ';
}
cout << endl;// 清空
dq1.clear();// 获取长度
cout << dq1.size() << ' ';// 判断是否为空
if( dq1.empty() ){cout << "empty" << endl;
}

6. 元组

6.1 二元组pair

pair<string, int> myPair0; // ("", 0)
pair<string, int> myPair1("pen", 20);
pair<string, int> myPair2={"pen", 5};
pair<string, int> myPair3 = make_pair("pensil", 2);// 访问pair元素
cout << myPair1.first << ": " << myPair1.second << endl;// 比较操作:多字段比较,即先比较first字段,再比较second字段
cout << "myPair1 > myPair2: " << (myPair1 > myPair2) << endl;  // 1: myPair1 > myPair2
cout << "myPair1 > myPair3: " << (myPair1 > myPair3) << endl;  // 0: myPair1 < myPair3,"pen" > "pensil"// 作为函数返回值类型
pair<int, string> response(int request){if(request == 0){return {200, "OK!"};} else {return {400. "Error!"}}
}// 交换pair
swap(myPair1, myPair2);

6.2 多元组tuple

6.2.1 创建和初始化

using namespace std;tuple<T1, T2, ..., TN> t1;      
tuple<T1, T2, ..., TN> t2(v1, v2, ... TN);
tuple<T1&> t3(ref&);
make_tuple(v1, v2);

6.2.2 tuple元素为引用类型时用例

string name;tuple<string &, int> tpRef( name, 27 );
get<0>(tpRef) = "aa"
cout << "name: " << name << endl;

6.2.3 基本操作

tuple<string, int> myTp( "Cg", 27 );
// 获取元素值,给出的索引需要是字面量,而不能是变量
auto tpElem = get<0>(myTp);// 获取元素个数
int tpNum = tuple_size<decltype(myTp)>::value;// 获取元素类型
tuple_element<1, decltype(myTp)>::type ages = get<1>(myTp);// 解包tuple分量
string name;
int age;
tie( name, age ) = myTp;
// 解包操作忽略第二个int型分量,使用std::ignore占位
tie( name, ignore ) = myTp;
// 集合make_tuple和引用来解包tuple,将myTp中元素解包到变量name,age
auto myTp1 = make_tuple(red(name), ref(age)) = myTp;// 元组的比较1:所有元素类型可比较,则整个元组可比较。比较运算符:>, <, ==, >=, <=
// 元组的比较2:存在不可比较的元素类型(自定义类型),需要自定义重载比较运算符号

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

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

相关文章

活码在实际操作中的具体场景有哪些?怎么应用?

当传统二维码因“内容固定、无法追踪、流量拥堵”等问题逐渐失效时&#xff0c;活码正在成为企业破解运营痛点的关键工具。 无论是需要实时更新内容的线下物料&#xff0c;还是面临用户分流压力的线上客服&#xff0c;动态二维码都能通过“一码多用、灵活配置”的特性&#xf…

极空间NAS部署gitea教程

极空间NAS部署gitea步骤教程 背景1. 准备镜像1.1 极空间官方1.2 Win系统docker再上传1.3 镜像转录 2. MySql配置2.1 容器配置2.2 命令行配置 3. gitea配置3.1 容器配置3.2 打开网页3.3 网页配置安装 参考资料 背景 极空间Nas和别的Nas不同的地方就在于&#xff0c;他不是那种标…

Wireshark:在 显示过滤器中“加入条件”过滤后,出现其他类型的数据包,为什么?

一、 在Wireshark中使用“tcp协议”过滤后&#xff0c;仍出现TLSv1.2协议的数据包&#xff0c;原因如下&#xff1a; 1. ‌协议层次关系‌ ‌TCP是传输层协议‌&#xff0c;而‌TLS属于应用层协议‌&#xff0c;后者直接运行于TCP之上‌28。因此&#xff0c;所有TLS流量&…

【医学影像 AI】大型语言模型生成 ROP 患者信息材料的能力

【医学影像 AI】大型语言模型生成 ROP 患者信息材料的能力 0. 论文简介0.1 基本信息0.2 摘要 1. 引言2. 材料与方法2.1 大语言模型的使用2.2 可读性标准2.3 统计分析 3. 结果3.1 Bezirci-Yılmaz可读性评分3.2 Ateşman可读性评分3.3 全面性评分3.4 准确性评分 4. 讨论4.1 可读…

设计模式(行为型)-策略模式

目录 定义 类图 角色 角色详解 Strategy&#xff08;抽象策略类&#xff09;​ Context&#xff08;环境类 / 上下文类&#xff09;​ ConcreteStrategy&#xff08;具体策略类&#xff09;​ 优缺点 优点​ 缺点​ 使用场景 类行为差异场景​ 动态算法选…

服装零售行业数字化时代的业务与IT转型规划P111(111页PPT)(文末有下载方式)

服装零售行业数字化时代的业务与IT转型规划P111 详细资料请看本解读文章的最后内容。 随着数字化技术的迅猛发展&#xff0c;服装零售行业正经历着前所未有的变革。本文将对《服装零售行业数字化时代的业务与IT转型规划P111》进行详细解读&#xff0c;探讨未来几年内该行业的…

【大语言模型_6】mindie启动模型错误整理

一、启动报 [hccl_runner.cpp:141] AllGatherHcclRunner:0 HcclCommInitRootInfo fa il, error:2, rank:0, rankSize:2 背景&#xff1a;运行DeepSeek-R1-Distill-Qwen-14B模型&#xff0c;在2张300 P卡可以运行&#xff0c;单独一张启动报以上错误。 问题分析&…

STM32F429单片机FMC接口驱动TFT LCD和SDRAM

1、FMC接口介绍 FMC 接口&#xff08;即可变存储控制器&#xff09;是一种用于管理外部存储器的外设接口&#xff0c;支持多种类型的存储器&#xff0c;主要分为三大类&#xff1a;NOR/SRAM/PSRAM设备&#xff08;TFTLCD相当于SRAM&#xff09;、NOR FLASH/NAND FLASH/PC卡设备…

ollama不安装到c盘,安装到其他盘

ollama 安装包默认安装到c盘&#xff0c;安装程序并没有提供选择文件夹安装功能&#xff0c;本来c盘就快满了&#xff0c;下几个模型c盘都快爆了&#xff0c;如何将ollma安装到其他盘呢&#xff1f; ollama 默认安装位置 C:\Users\Admin\.ollama 是 Ollama 用来放大模型的文件夹…

java项目之基于ssm的少儿编程在线培训系统(源码+文档)

项目简介 少儿编程在线培训系统实现了以下功能&#xff1a; 用户信息管理&#xff1a; 用户信息新增 用户信息修改 教师信息管理&#xff1a; 教师信息添加 教师信息删除 教师信息修改 课程信息管理&#xff1a; 课程信息添加 课程信息修改 课程信息删除 课程类型管理&…

Cinema4D安装及基本操作

一、简介 Cinema 4D&#xff08;C4D&#xff09;是德国 Maxon Computer 开发的 3D 软件&#xff0c;具备强大的建模、动画、材质、渲染功能&#xff0c;以易用高效著称&#xff0c;广泛应用于影视、游戏、设计等领域&#xff0c;是行业内主流 3D 创作工具。 二、安装 1.下载安…

为什么TCP需要三次握手?一次不行吗?

文章目录 1. 三次握手的过程2. 为什么需要三次握手&#xff1f;3. 握手过程中每一步的具体作用4. 简单比喻5. 为什么是三次握手&#xff0c;而不是两次或四次&#xff1f;6. 三次握手中的序列号有什么作用&#xff1f;7. 总结 1. 三次握手的过程 三次握手是建立 TCP 连接的过程…

大数据在人力资源管理中的洞察与决策

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字化转型浪潮中&#xff0c;人力资源管理&#xff08;HRM&#xff09;正经历着前所未有的变革。…

让vscode远程开发也可以图形显示

目录 0. 摘要1. 保存查看2. jupyter内置inline渲染3. jupyter浏览器4. matplot修改后端5. SSH X11转发[※]6. 参考 0. 摘要 vscode登录远程服务器进行开发遇到图形显示需求时&#xff0c;该怎么处理&#xff1f;一般有几种方式&#xff1a; 保存下来查看jupyter内置的inline图…

Blender制作次表面材质

效果: 主要用沃罗诺伊纹理做出云絮感 然后EV开启次表面设置

服务器数据恢复—服务器raid故障导致上层分区不可用的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台服务器中有一组由三块SAS硬盘组建的raid阵列。服务器上部署的数据库存储在D分区&#xff0c;数据库备份存储在E分区。 服务器上一块硬盘指示灯显示红色。D分区不可识别。E分区虽然可以识别&#xff0c;但是E分区拷贝文件报错。 管…

PyTorch PINN实战:用深度学习求解微分方程

神经网络技术已在计算机视觉与自然语言处理等多个领域实现了突破性进展。然而在微分方程求解领域&#xff0c;传统神经网络因其依赖大规模标记数据集的特性而表现出明显局限性。物理信息神经网络(Physics-Informed Neural Networks, PINN)通过将物理定律直接整合到学习过程中&a…

关于“碰一碰发视频”系统的技术开发文档框架

以下是关于“碰一碰发视频”系统的技术开发文档框架&#xff0c;涵盖核心功能、技术选型、开发流程和关键模块设计&#xff0c;帮助您快速搭建一站式解决方案 --- 随着短视频平台的兴起&#xff0c;用户的创作与分享需求日益增长。而如何让视频分享更加便捷、有趣&#xff0c…

【VUE】day05-ref引用

这里写目录标题 1. ref引用1.1 使用ref引用组件 2. this.$nextTick(cb)方法3. 购物车案例3.1 数组中的方法 - some循环3.2 数组中的方法 - every循环3.3 数组中的方法 - reduce 4. 购物车案例 1. ref引用 ref用来辅助开发者在不依赖于jQuery的情况下&#xff0c;获取DOM元素或…

docker安装milvus向量数据库Attu可视化界面

Docker 部署 Milvus 及 Attu 可视化工具完整指南 一、环境准备 安装 Docker 及 Docker Compose Docker 版本需 ≥20.10.12Docker Compose 版本需 ≥2.20.0&#xff08;推荐 V2&#xff09; 验证 Docker 环境 docker --version && docker-compose --version若出现&…