十四天学会C++之第七天:STL(标准模板库)
1. STL容器
- 什么是STL容器,为什么使用它们。
- 向量(vector):使用向量存储数据。
- 列表(list):使用列表实现双向链表。
- 映射(map):使用映射实现键值对存储。
什么是STL容器?
STL容器是一种用于存储和管理数据的C++模板类,它们提供了多种数据结构,以满足不同的需求。STL容器分为序列容器(Sequence Containers)和关联容器(Associative Containers)两大类。序列容器类似于数组,关联容器则基于键值对存储数据。
向量(vector)
向量是序列容器中最常用的之一,它类似于动态数组。它具有自动扩展和收缩的能力,因此可以根据需要存储任意数量的元素。
#include <vector>
#include <iostream>int main() {std::vector<int> myVector; // 创建一个整数向量// 向向量中添加元素myVector.push_back(1);myVector.push_back(2);myVector.push_back(3);// 遍历并输出向量中的元素for (int i : myVector) {std::cout << i << " ";}return 0;
}
列表(list)
列表是双向链表的实现,提供了高效的插入和删除操作。与向量不同,列表的元素在内存中不是连续存储的,因此适用于需要频繁插入和删除操作的情况。列表的简单示例:
#include <list>
#include <iostream>int main() {std::list<std::string> myList; // 创建一个字符串列表// 向列表中添加元素myList.push_back("Hello");myList.push_back("World");myList.push_front("C++");// 遍历并输出列表中的元素for (const std::string& str : myList) {std::cout << str << " ";}return 0;
}
映射(map)
映射是关联容器,它将键与值关联起来,允许通过键快速查找对应的值。这在需要构建字典、查找表或关系映射时非常有用。以下是一个映射的简单示例:
#include <map>
#include <iostream>int main() {std::map<std::string, int> myMap; // 创建一个字符串到整数的映射// 向映射中添加键值对myMap["apple"] = 5;myMap["banana"] = 3;myMap["cherry"] = 8;// 查找并输出映射中的值std::cout << "The number of bananas is: " << myMap["banana"] << std::endl;return 0;
}
STL容器的强大功能使它们成为C++开发中不可或缺的一部分。无论你的项目规模如何,STL都提供了各种工具,用于有效地管理和操作数据,让代码更加高效和可维护。
2. STL算法
- 什么是STL算法,它们的作用。
- 排序算法:介绍STL的排序算法。
- 查找算法:介绍STL的查找算法。
- 使用STL算法来处理容器中的数据。
什么是STL算法?
STL算法是一组通用的、可复用的算法,它们独立于特定的容器类型,可以用于处理各种数据结构。STL算法可以显著提高代码的可读性和可维护性,同时还能提供高效的性能。
排序算法
STL提供了多种排序算法,其中最常用的是std::sort()函数,它可以对容器中的元素进行升序排序。排序算法:
#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> numbers = {5, 2, 8, 1, 9};// 使用std::sort()对向量进行升序排序std::sort(numbers.begin(), numbers.end());// 输出排序后的结果for (int num : numbers) {std::cout << num << " ";}return 0;
}
查找算法
STL还提供了多种查找算法,其中包括std::find()函数,它可以在容器中查找指定的元素。
#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> numbers = {5, 2, 8, 1, 9};int target = 8;// 使用std::find()在向量中查找目标元素auto result = std::find(numbers.begin(), numbers.end(), target);// 检查查找结果if (result != numbers.end()) {std::cout << "Found " << target << " at position " << (result - numbers.begin()) << std::endl;} else {std::cout << target << " not found." << std::endl;}return 0;
}
使用STL算法处理容器中的数据
STL算法通常以迭代器作为参数,因此它们可以应用于各种容器,如向量、列表、映射等。这使得算法非常通用和灵活。你可以使用std::for_each()、std::transform()等算法来遍历容器中的元素,执行自定义的操作。
3. 自定义模板
- 什么是模板,为什么使用模板。
- 函数模板:创建可以处理不同数据类型的通用函数。
- 类模板:创建可以处理不同数据类型的通用类。
什么是模板?
模板是一种通用的代码蓝图,它允许你编写可以处理不同数据类型的代码。C++中有两种主要类型的模板:函数模板和类模板。
函数模板
函数模板允许你编写通用的函数,这些函数可以接受不同类型的参数。函数模板的定义以template关键字开始,后跟模板参数列表和函数声明。
简单的函数模板,用于交换两个值:
template <typename T>
void swapValues(T &a, T &b) {T temp = a;a = b;b = temp;
}int main() {int x = 5, y = 10;double a = 3.14, b = 2.71;swapValues(x, y); // 交换整数swapValues(a, b); // 交换双精度浮点数return 0;
}
函数模板的typename T部分表示模板参数,它可以是任何数据类型。
类模板
类模板允许你编写通用的类,这些类可以处理不同类型的成员变量和成员函数。类模板的定义以template关键字开始,后跟模板参数列表和类定义。
类模板,用于创建通用的栈数据结构:
template <typename T>
class Stack {
public:Stack() : top(-1) {}void push(T item) {if (top < MaxSize - 1) {data[++top] = item;}}T pop() {if (top >= 0) {return data[top--];} else {// 处理栈为空的情况throw std::runtime_error("Stack is empty");}}private:static const int MaxSize = 100;T data[MaxSize];int top;
};int main() {Stack<int> intStack;intStack.push(5);intStack.push(10);int x = intStack.pop(); // 弹出值为10的元素Stack<double> doubleStack;doubleStack.push(3.14);doubleStack.push(2.71);double y = doubleStack.pop(); // 弹出值为2.71的元素return 0;
}
类模板的typename T部分表示模板参数,可以是任何数据类型。
为什么使用模板?
使用模板可以使代码更加通用和灵活,无需为不同的数据类型编写重复的代码。模板还有助于提高代码的可维护性,只需编写一次通用代码,即可适用于多种数据类型。
4. 示例和练习
使用STL容器
使用STL容器的示例代码,演示向量(vector)的用法,包括添加元素、遍历容器和查找元素:
#include <iostream>
#include <vector>int main() {std::vector<int> numbers; // 创建整数向量// 向向量添加元素numbers.push_back(1);numbers.push_back(2);numbers.push_back(3);// 遍历向量并输出元素for (int num : numbers) {std::cout << num << " ";}// 查找元素是否存在int target = 2;auto it = std::find(numbers.begin(), numbers.end(), target);if (it != numbers.end()) {std::cout << "\n" << target << " found at position " << std::distance(numbers.begin(), it);} else {std::cout << "\n" << target << " not found";}return 0;
}
使用STL算法
使用STL算法的示例代码,演示排序和查找算法的用法:
#include <iostream>
#include <vector>
#include <algorithm>int main() {std::vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};// 排序向量std::sort(numbers.begin(), numbers.end());// 输出排序后的向量for (int num : numbers) {std::cout << num << " ";}// 使用二分查找查找元素int target = 5;if (std::binary_search(numbers.begin(), numbers.end(), target)) {std::cout << "\n" << target << " found";} else {std::cout << "\n" << target << " not found";}return 0;
}
使用模板
使用函数模板的示例代码,如何创建一个通用的函数来比较两个值:
#include <iostream>template <typename T>
bool isEqual(T a, T b) {return a == b;
}int main() {int x = 5, y = 5;double a = 3.14, b = 2.71;if (isEqual(x, y)) {std::cout << "x and y are equal\n";} else {std::cout << "x and y are not equal\n";}if (isEqual(a, b)) {std::cout << "a and b are equal\n";} else {std::cout << "a and b are not equal\n";}return 0;
}
练习题
创建一个向量,存储一组学生的分数,并计算平均分。
#include <iostream>
#include <vector>int main() {std::vector<double> scores; // 创建一个双精度浮点数向量来存储学生的分数// 向向量添加学生分数scores.push_back(85.5);scores.push_back(92.0);scores.push_back(78.5);scores.push_back(88.0);scores.push_back(90.5);// 计算平均分double sum = 0.0;for (double score : scores) {sum += score;}double average = sum / scores.size();// 输出平均分std::cout << "平均分: " << average << std::endl;return 0;
}
运行结果:

解答:
- 首先,包含
<iostream>和<vector>头文件来使用C++的标准输入输出和向量容器。 - 然后,创建一个
std::vector<double>类型的向量,用于存储学生的分数。 - 使用
push_back函数将分数添加到向量中。 - 通过迭代向量中的分数,计算它们的总和并除以向量的大小来获得平均分。
- 最后,输出平均分。
使用STL的列表容器存储一组单词,并按字母顺序排序。
#include <iostream>
#include <list>
#include <algorithm>int main() {std::list<std::string> words; // 创建一个字符串列表来存储单词// 向列表添加单词words.push_back("apple");words.push_back("banana");words.push_back("cherry");words.push_back("date");words.push_back("fig");// 使用STL的排序算法对单词进行排序words.sort();// 遍历并输出排序后的单词for (const std::string& word : words) {std::cout << word << " ";}return 0;
}
运行结果:

解答:
- 包含了
<iostream>和<list>头文件,以便使用C++的标准输入输出和列表容器。 - 然后,创建一个
std::list<std::string>类型的列表,用于存储单词。 - 使用
push_back函数将单词添加到列表中。 - 使用
sort函数对列表中的单词进行字母顺序排序。 - 最后,遍历并输出排序后的单词。
创建一个通用的函数模板,用于计算两个数的最大值。
#include <iostream>template <typename T>
T findMax(T a, T b) {return (a > b) ? a : b;
}int main() {int intMax = findMax(42, 17);double doubleMax = findMax(3.14, 2.71);std::cout << "最大整数值: " << intMax << std::endl;std::cout << "最大双精度浮点数值: " << doubleMax << std::endl;return 0;
}
运行结果:

解答:
- 定义一个通用函数模板
findMax,它可以接受任何类型的参数a和b。 - 函数模板的返回类型也是参数的类型。
- 在
main函数中,演示如何使用这个模板函数来查找整数和双精度浮点数的最大值。
创建一个类模板,表示二维坐标点,包括x和y坐标。
#include <iostream>template <typename T>
class Point {
public:Point(T x, T y) : x_(x), y_(y) {}void display() const {std::cout << "X坐标: " << x_ << ", Y坐标: " << y_ << std::endl;}private:T x_;T y_;
};int main() {Point<int> intPoint(2, 3);Point<double> doublePoint(1.5, 2.0);std::cout << "整数坐标点:" << std::endl;intPoint.display();std::cout << "双精度浮点数坐标点:" << std::endl;doublePoint.display();return 0;
}
运行结果:

解答:
- 定义一个类模板
Point,它有两个模板参数typename T,表示x和y坐标的类型。 - 类模板有一个构造函数,可以接受两个参数,分别用于初始化x和y坐标。
- 类模板还有一个成员函数
display,用于显示坐标点的值。 - 在
main函数中,我们演示了如何创建不同类型的坐标点。
使用STL的映射容器存储学生的姓名和分数,然后按姓名查找分数。
#include <iostream>
#include <map>
#include <string>int main() {std::map<std::string, double> studentScores; // 创建一个映射容器,姓名映射到分数// 向映射容器添加学生和分数studentScores["Alice"] = 90.5;studentScores["Bob"] = 88.0;studentScores["Charlie"] = 92.5;studentScores["David"] = 85.0;// 按姓名查找分数std::string nameToFind = "Bob";if (studentScores.find(nameToFind) != studentScores.end()) {double score = studentScores[nameToFind];std::cout << nameToFind << " 的分数是 " << score << std::endl;} else {std::cout << "找不到学生:" << nameToFind << std::endl;}return 0;
}
运行结果:

解答:
- 使用
std::map容器来创建一个学生姓名到分数的映射。 - 使用方括号操作符
[]添加学生和分数的映射。 - 使用
find函数按姓名查找分数,如果找到,就输出分数;如果找不到,就输出找不到的消息。
相关文章:
十四天学会C++之第七天:STL(标准模板库)
1. STL容器 什么是STL容器,为什么使用它们。向量(vector):使用向量存储数据。列表(list):使用列表实现双向链表。映射(map):使用映射实现键值对存储。 什么…...
Linux 下安装 miniconda,管理 Python 多环境
安装 miniconda 1、下载安装包 Miniconda3-py37_22.11.1-1-Linux-x86_64.sh,或者自行选择版本 2、把安装包上传到服务器上,这里放在 /home/software 3、安装 bash Miniconda3-py37_22.11.1-1-Linux-x86_64.sh 4、按回车 Welcome to Miniconda3 py37…...
Django和jQuery,实现Ajax表格数据分页展示
1.需求描述 当存在重新请求接口才能返回数据的功能时,若页面的内容很长,每次点击一个功能,页面又回到了顶部,对于用户的体验感不太友好,我们希望当用户点击这类的功能时,能直接加载到数据,请求…...
k8s认证
1. 证书介绍 服务端保留公钥和私钥,客户端使用root CA认证服务端的公钥 一共有多少证书: *Etcd: Etcd对外提供服务,要有一套etcd server证书Etcd各节点之间进行通信,要有一套etcd peer证书Kube-APIserver访问Etcd&a…...
基于python开发的IP修改工具
工作中调试设备需要经常修改电脑IP,非常麻烦,这里使用Pythontkinter做了一个IP修改工具 说明: 1.启动程序读取config.json文件2.如果没有该文件则创建,写入当前网卡信息3.通过配置信息进行网卡状态修改4.更新文件状态,删除或修…...
Mybatis源码分析
1. Mybatis整体三层设计 SSM中,Spring、SpringMVC已经在前面文章源码分析总结过了,Mybatis源码相对Spring和SpringMVC而言是的简单的,只有一个项目,项目下分了很多包。从宏观上了解Mybatis的整体框架分为三层,分别是基…...
python树结构包treelib入门及其计算应用
树是计算机科学中重要的数据结构。例如决策树等机器学习算法设计、文件系统索引等。创建treelib包是为了在Python中提供树数据结构的有效实现。 Treelib的主要特点包括: 节点搜索的高效操作。支持常见的树操作,如遍历、插入、删除、节点移动、浅/深复制…...
Rust之自动化测试(三): 测试组合
开发环境 Windows 10Rust 1.73.0 VS Code 1.83.1 项目工程 这里继续沿用上次工程rust-demo 测试组合 正如本章开始时提到的,测试是一个复杂的学科,不同的人使用不同的术语和组织。Rust社区根据两个主要类别来考虑测试:单元测试和集成测试。单元测试很…...
专业管理菜单的增删改、查重
1,点击专业管理菜单------查询所有专业信息列表 ①点击菜单,切换专业组件 ②切换到列表组件后,向后端发送请求到Servlet ③调用DAO层,查询数据库(sql),封装查询到的内容 ④从后端向前端做出…...
vue3插件开发,上传npm
创建插件 在vue3工程下,创建组件vue页: toolset.vue。并设置组件名称。注册全局组件。新建index.js文件。内容如下,可在main.js中引入index.js,注册该组件进行测试。API服务是LLM(大语言模型)开放接口平台:持续接入各种主流的大模型接口,并提供简单、易用、统一的API交互…...
【python】屈小原现在要为学校写校庆贺文(CTGU百年校庆)
题目: """ 题目描述: 屈小原需要为学校的校庆写一篇贺文,共需写下n个字,但他目前只完成了1个字。屈小原可以进行两种操作: 在文档的末尾添加一个字,这样字数就会变为x1。 写下与当前字数相同…...
探索未来的视觉革命:卷积神经网络的崭新时代(二)
💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…...
博客后台模块续更(三)
四、后台模块-动态路由 实现了这个动态路由功能之后,就能在浏览器web页面登录进博客管理后台了 1. 接口分析 后台系统需要能实现不同的用户权限可以看到不同的功能,即左侧的导航栏 请求方式 请求地址 请求头 GET /getRouters 需要token请求头 …...
第十二届蓝桥杯模拟赛第三期
A填空题 问题描述 请问在 1 到 2020 中,有多少个数与 2020 互质,即有多少个数与 2020 的最大公约数为 1。 参考答案 800 public class Main {public static void main(String[] args) {int ans0;for(int i1;i<2020;i) {if(gcd(2020,i)1) {ans;}}…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
