C++ STL 学习指南:带你快速掌握标准模板库

news2024/11/23 3:13:20

🌟快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。 🌟

 

大家好呀!🤗 今天我们来聊一聊 C++ 程序员的必备神器——STL(Standard Template Library,标准模板库)。如果你是 C++ 初学者或者还没深入了解过 STL 的朋友,这篇文章将带你快速入门,揭开 STL 的神秘面纱!😎

 你是否觉得自己在 C++ 中经常需要实现一些重复的代码,比如排序、查找数据、动态数组扩容等等? 如果你也有这样的烦恼,那么 STL 可以完美解决这些问题!它能够极大地简化我们的代码,减少不必要的工作量,同时提高开发效率。💡


目录

什么是 STL?🔍

一、容器(Containers):你的数据储物箱 🧰

1. vector:动态数组 💡

vector的实战案例 📊

2. list:双向链表 🔗

list的妙用

3. map:键值对存储 🗂️

使用 map 进行数据统计

4. unordered_map:哈希表 🧩

5. stack 和 queue:方便的数据处理 🍰

二、算法(Algorithms):高效的代码助推器 🏎️

1. 排序与查找:sort 和 find 🌠

2. 统计与累加:count 和 accumulate 📊

3. 自定义操作:for_each 函数 ✨

三、迭代器(Iterators):容器与算法的桥梁 🌉

迭代器的种类

迭代器的实际应用 🚀

四、总结:STL 的使用技巧 🌟


什么是 STL?🔍

STL 是 C++ 的标准库之一,包含了一系列 模板类函数模板,主要用于提供通用的数据结构和算法。简单来说,STL 就是帮你解决“重复造轮子”的问题,让你更专注于实现逻辑,而不是耗费时间在基础数据结构的实现上。

STL 包含了三个核心组件:

  1. 容器(Containers) 🚀:用于存储数据的集合,比如 vectorlistmap 等。
  2. 算法(Algorithms) 🛠️:常用算法的集合,比如排序、查找、遍历等。
  3. 迭代器(Iterators) 🔄:连接容器与算法的“桥梁”,用于遍历容器内的元素。

接下来,我们将依次了解这些组件,看看 STL 是如何让编程变得更轻松的!🌈


一、容器(Containers):你的数据储物箱 🧰

容器是 STL 的核心部分,提供了多种数据存储结构。每种容器都有各自的特点和适用场景,以下是一些常见的容器:

1. vector:动态数组 💡

vector 是一种动态数组,可以根据需要自动扩展容量。它的特点是 支持随机访问,并且在末尾添加和删除元素的效率很高。

vector的实战案例 📊
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3};
    vec.push_back(4);  // 在末尾添加元素
    vec.push_back(5);
    vec[1] = 10;       // 修改第二个元素

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

 

适用场景:当你需要频繁读取某个位置的元素时,vector 是首选!✨

注意事项vector 的扩容是成倍增长的,因此它有时会多分配一些内存来应对未来的增长。如果能提前知道数据量的大小,最好使用 reserve() 减少扩容带来的性能开销。

2. list:双向链表 🔗

list 是双向链表,适合在任意位置进行插入和删除操作。与 vector 不同的是,它不支持随机访问,因此访问某个特定位置的元素效率较低。

list的妙用
#include <list>
#include <iostream>

int main() {
    std::list<int> lst = {1, 2, 3};
    lst.push_front(0);  // 在开头添加元素
    lst.push_back(4);   // 在末尾添加元素
    lst.insert(++lst.begin(), 100);  // 在第二个位置插入 100

    for (int num : lst) {
        std::cout << num << " ";
    }
    return 0;
}

 

适用场景:如果你的程序需要频繁插入和删除元素,而对随机访问的需求不高,list 会是更好的选择!😉

实际体验:在某些情况下,使用list 进行插入操作的代码比 vector 更加简洁和高效,尤其是在需要频繁的插入和删除操作时。

3. map:键值对存储 🗂️

map 是一种关联容器,基于红黑树实现,可以用来存储键值对(key-value)。map 自动对键进行排序,并且不允许键重复。

使用 map 进行数据统计
#include <map>
#include <iostream>

int main() {
    std::map<std::string, int> ages;
    ages["Alice"] = 25;
    ages["Bob"] = 30;
    ages["Charlie"] = 22;

    // 输出所有人的年龄
    for (const auto& pair : ages) {
        std::cout << pair.first << ": " << pair.second << "\n";
    }
    return 0;
}

适用场景:当你需要根据键快速查找对应值时,map 是一个非常方便的选择!✨

个人经验分享:如果你的程序需要频繁修改数据,可以选择 unordered_map,它的查找效率更高,但不保证有序性。

4. unordered_map:哈希表 🧩

unordered_map 类似于 map,但是它使用哈希表实现,因此查找速度在平均情况下更快。它不保证元素的顺序。

使用unordered_map 的小窍门unordered_map 使用的是哈希函数,因此如果你的键是自定义类型,请记得实现适当的哈希函数,否则可能会出现编译错误。

5. stack queue:方便的数据处理 🍰

stack queue 是两种特殊的容器适配器,分别实现了 后进先出(LIFO)和 先进先出(FIFO)的数据处理模式。

示例代码:

#include <stack>
#include <queue>
#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();
    }

    std::queue<int> que;
    que.push(1);
    que.push(2);
    que.push(3);
    while (!que.empty()) {
        std::cout << que.front() << " ";
        que.pop();
    }
    return 0;
}

适用场景stack 适用于需要处理递归或回退逻辑的场景,而 queue 适用于按顺序处理数据的情况,例如任务排队。 


二、算法(Algorithms):高效的代码助推器 🏎️

STL 的算法库提供了丰富的工具,使得编程变得更加简单。你可以使用这些算法来处理容器中的数据,而不用重复编写类似的逻辑代码。

1. 排序与查找:sortfind 🌠

  • sort():可以轻松对容器进行排序。
  • find():在容器中查找指定元素。

 示例代码:

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {5, 2, 9, 1, 5, 6};
    std::sort(vec.begin(), vec.end()); // 排序
    auto it = std::find(vec.begin(), vec.end(), 9); // 查找

    if (it != vec.end()) {
        std::cout << "Found: " << *it << "\n";
    } else {
        std::cout << "Not found\n";
    }

    return 0;
}

 

亲身体验:使用 STL 的算法库,可以让你把更多精力放在业务逻辑上,而不是实现底层算法,这就是 STL 的魅力所在。🔥

2. 统计与累加:countaccumulate 📊

  • count():统计某个元素在容器中出现的次数。
  • accumulate():累加容器中的元素。
#include <vector>
#include <numeric> // 包含 accumulate
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 3, 2, 3};
    int count3 = std::count(vec.begin(), vec.end(), 3); // 统计3的数量
    int sum = std::accumulate(vec.begin(), vec.end(), 0); // 求和

    std::cout << "Number of 3s: " << count3 << "\n";
    std::cout << "Sum: " << sum << "\n";

    return 0;
}

3. 自定义操作:for_each 函数 ✨

for_each 函数可以帮助你对容器中的每个元素进行自定义操作,比如打印每个元素、改变它们的值等等。

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::for_each(vec.begin(), vec.end(), [](int& num) {
        num *= 2; // 将每个元素乘以2
        std::cout << num << " ";
    });
    return 0;
}
v

 应用场景:如果你有特定的逻辑想要应用到容器中的每个元素,for_each 非常好用,可以用 Lambda 表达式让代码更加简洁。

 


三、迭代器(Iterators):容器与算法的桥梁 🌉

迭代器是 STL 的精髓,它让你可以方便地遍历容器中的元素,同时与 STL 的算法进行无缝配合。

迭代器的种类

  • 输入迭代器(Input Iterator):只读。
  • 输出迭代器(Output Iterator):只写。
  • 前向迭代器(Forward Iterator):可读写,可向前遍历。
  • 双向迭代器(Bidirectional Iterator):可向前和向后遍历。
  • 随机访问迭代器(Random Access Iterator):支持随机访问,类似指针。

迭代器的实际应用 🚀

#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用正向迭代器
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";

    // 使用反向迭代器
    for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
        std::cout << *rit << " ";
    }

    return 0;
}

 经验分享:通过熟练掌握迭代器,你可以实现对各种容器的灵活操作,使代码更加优雅、简洁。迭代器甚至可以用来实现自定义算法,非常强大!💪

 


四、总结:STL 的使用技巧 🌟

在日常开发中,合理使用 STL 可以大幅提升代码的效率和简洁性。以下是一些 STL 使用的小技巧:

  1. 选择合适的容器:根据需求选择合适的容器,比如频繁访问使用 vector,频繁插入删除使用 list,键值对查找使用 map
  2. 使用算法库:STL 中的算法库包含了常用的排序、查找、计算等函数,避免重复造轮子!
  3. 掌握迭代器:迭代器是 STL 的精髓,熟练掌握迭代器可以使你的代码更灵活、更高效。
  4. 预分配容量:对于 vector,如果可以预知数据量,使用 reserve() 预分配容量可以减少扩容带来的性能损耗。
  5. 注意迭代器失效:某些操作(如在 vector 中插入或删除元素)会导致迭代器失效,务必小心处理。

希望通过这篇文章,大家对 C++ 的 STL 有了一个初步了解!🎉 STL 是 C++ 中非常强大的一部分,如果你能熟练使用 STL,将会让你的编程效率提升一大步!🚀

别忘了给文章点个赞👍,让更多人了解 STL 的魅力吧!如有问题,欢迎在评论区交流讨论!😊

 欢迎关注我👉【A Charmer】

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

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

相关文章

NIO 核心知识总结

在传统的 Java I/O 模型&#xff08;BIO&#xff09;中&#xff0c;I/O 操作是以阻塞的方式进行的。也就是说&#xff0c;当一个线程执行一个 I/O 操作时&#xff0c;它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈&#xff0c;因为需要为每个连…

从“点”到“面”,热成像防爆手机如何为安全织就“透视网”?

市场上测温产品让人眼花缭乱&#xff0c;通过调研分析&#xff0c;小编发现测温枪占很高比重。但是&#xff0c;测温枪局限于显示单一数值信息&#xff0c;无法直观地展示物体的整体温度分布情况&#xff0c;而且几乎没有功能拓展能力。以AORO A23为代表的热成像防爆手机改变了…

Linux·进程控制(system V)

1. 共享内存 system V共享内存是最快的IPC形式&#xff0c;之前的管道是基于Linux内核开发的通讯方案&#xff0c;其读写接口都是现成的&#xff0c;因此内核设计者为了完成进程间通讯任务并不需要新增太多代码。而共享内存属于system V标准&#xff0c;是操作系统单独…

C# CSV工具类,读取csv文件、将数据导出为csv文件格式,用DataGridView表格控件显示

CSVHelper.cs工具类能够将CSV格式的文件读取到程序中&#xff0c;转换为内存中DataTable类型的数据&#xff0c;可以作为数据源直接给到DataGridView控件以表格形式显示csv中的数据。也可以导出程序中DataTable类型数据为CSV文件。 使用示例&#xff1a; 1、准备一个csv文件 2…

qt QMenuBar详解

1、概述 QMenuBar是Qt框架中用于创建菜单栏的类&#xff0c;它继承自QWidget。QMenuBar通常位于QMainWindow对象的标题栏下方&#xff0c;用于组织和管理多个QMenu&#xff08;菜单&#xff09;和QAction&#xff08;动作&#xff09;。菜单栏提供了一个水平排列的容器&#x…

Ubuntu用docker安装AWVS和Nessus(含破解)

Ubuntu安装AWVS(更多搜索&#xff1a;超详细Ubuntu用docker安装AWVS和Nessus) 首先安装docker&#xff0c;通过dockers镜像安装很方便&#xff0c;且很快&#xff1b;Docker及Docker-Compose-安装教程。 1.通过docker search awvs命令查看镜像&#xff1b; docker search awvs…

SpringBoot篇(简化操作的原理)

目录 一、代码位置 二、统一版本管理&#xff08;parent&#xff09; 三、提供 starter简化 Maven 配置 四、自动配置 Spring&#xff08;引导类&#xff09; 五、嵌入式 servlet 容器 一、代码位置 二、统一版本管理&#xff08;parent&#xff09; SpringBoot项目都会继…

Spring 框架精髓:从基础到分布式架构的进阶之路

一、概述 &#xff08;一&#xff09;Spring框架概念 1.概念&#xff1a; Spring框架是一个用于简化Java企业级应用开发的开源应用程序框架。 2.Spring框架的核心与提供的技术支持&#xff1a; 核心&#xff1a; IoC控制反转|反转控制&#xff1a;利用框架创建类的对象的…

[vulnhub]DC: 5

https://www.vulnhub.com/entry/dc-5,314/ 主机发现端口扫描 探测存活主机&#xff0c;175是靶机 nmap -sP 192.168.75.0/24 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-02 13:27 CST Nmap scan report for 192.168.75.1 Host is up (0.00022s latency). MAC Addr…

C语言_数据结构_顺序表

1. 本章重点 顺序表初始化顺序表尾插顺序表尾删顺序表头插顺序表头删顺序表查找顺序表在pos位置插入x顺序表删除pos位置的值顺序表销毁顺序表打印 2. 顺序表的概念及结构 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储…

形态学操作篇 原理公式代码齐活

一、腐蚀 腐蚀操作的核心原理是利用一个结构元素在图像上进行扫描&#xff0c;判断结构元素所覆盖的区域与前景像素的关系。如果结构元素完全被包含在前景像素区域内&#xff0c;那么结构元素中心对应的像素位置在腐蚀后的图像中被标记为前景像素&#xff1b;如果结构元素不完…

小北的字节跳动青训营与 LangChain 实战课:探索 AI 技术的新边界(持续更新中~~~)

前言 最近&#xff0c;字节跳动的青训营再次扬帆起航&#xff0c;作为第二次参与其中的小北&#xff0c;深感荣幸能借此机会为那些尚未了解青训营的友友们带来一些详细介绍。青训营不仅是一个技术学习与成长的摇篮&#xff0c;更是一个连接未来与梦想的桥梁~ 小北的青训营 X M…

【SSM详细教程】-15-Spring Restful风格【无敌详细】

精品专题&#xff1a; 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…

使用Python爬取某发地网市场蔬菜价格数据

前言 随着互联网技术的发展&#xff0c;数据抓取成为了获取大量公开数据的重要手段。本文将介绍如何利用 Python 编程语言结合 DrissionPage 和自定义的 DataRecorder 模块&#xff0c;实现对新发地市场蔬菜价格数据的自动化抓取&#xff0c;并将抓取到的数据保存至 CSV 文件中…

免费好用又好看且多端自动同步第三方终端工具Termius你值得拥有

使用目的&#xff1a; 本地终端功能一样&#xff0c;都是为了登录服务器查看日志等操作。 本地终端 优点&#xff1a;方便简单&#xff0c;无需额外下载安装、免费。 缺点&#xff1a;每次都需要重新登陆输入命令&#xff0c;步骤繁琐无法简化&#xff1b;不能跨端同步。 第…

Postman:高效的API测试工具

在现代软件开发中&#xff0c;前后端分离的架构越来越普遍。前端开发者与后端开发者之间的协作需要一种高效的方式来测试和验证API接口。在这个背景下&#xff0c;Postman作为一款强大的API测试工具&#xff0c;受到了广泛的关注和使用。 今天将介绍什么是Postman、为什么要使用…

计算机网络-以太网小结

前导码与帧开始分界符有什么区别? 前导码--解决帧同步/时钟同步问题 帧开始分界符-解决帧对界问题 集线器 集线器通过双绞线连接终端, 学校机房的里面就有集线器 这种方式仍然属于共享式以太网, 传播方式依然是广播 网桥: 工作特点: 1.如果转发表中存在数据接收方的端口信息…

基于Retinex算法的图像去雾matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 2.算法运行软件版本 matlab2022a 3.部分核心程序 &#xff08;完整版代码包含详细中文注释和操作步骤视频&#xff09…

Nature Medicine病理AI汇总|TORCH:预测未知原发部位癌症的肿瘤起源|顶刊精析·24-11-01

小罗碎碎念 今天分析Nature Medicine病理AI系列的第三篇文章——《Prediction of tumor origin in cancers of unknown primary origin with cytology-based deep learning》 这篇文章报道了一种基于细胞学图像的深度学习方法TORCH&#xff0c;用于预测未知原发部位癌症的肿瘤…

Ubuntu 安装CUDA, cuDNN, TensorRT(草稿)

文章目录 写在前面一、CUDA, cuDNN, TensorRT 三个库的版本的确定二、解决方法参考链接 写在前面 自己的测试环境&#xff1a; Ubuntu20.04, 本文安装的版本&#xff1a; cuda_11.1.0&#xff1b;cuDNN-8.2.1&#xff1b;TensorRT-8.2.4.2 一、CUDA, cuDNN, TensorRT 三个库…