C++标准库学习(刷题应用)

news/2024/9/21 21:57:25

参考自菜鸟教程,用于熟悉C++常用容器刷题应用

C++ STL

  • STL核心组件:
    • 容器(Containers):向量(vector)、链表(list)、队列(queue)、栈(stack)、集合(set)、映射(map)等;
      • 序列容器:存储元素的序列,允许双向遍历
        • std::vector:动态数组,支持快速随机访问。
        • std::deque:双端队列,支持快速插入和删除。
        • std::list:链表,支持快速插入和删除,但不支持随机访问。
      • 关联容器:存储键值对,每个元素都有一个键(key)和一个值(value),并且通过键来组织元素
        • std::set:集合,不允许重复元素。
        • std::multiset:多重集合,允许多个元素具有相同的键。
        • std::map:映射,每个键映射到一个值。
        • std::multimap:多重映射,允许多个键映射到相同的值。
      • 无序容器(C++11 引入):哈希表,支持快速的查找、插入和删除
        • std::unordered_set:无序集合。
        • std::unordered_multiset:无序多重集合。
        • std::unordered_map:无序映射。
        • std::unordered_multimap:无序多重映射。
    • 算法(Algorithms):排序、搜索、复制、移动、变换等;
    • 迭代器(iterators):随机访问迭代器、双向迭代器、前向迭代器和输入输出迭代器等;
    • 函数对象(Function Objects):可以像函数一样调用的对象,可用于算法中的各种操作。包括一元函数对象、二元函数对象、谓词等。
    • 适配器(Adapters):用于将一种容器或迭代器适配成另一种容器或迭代器,以满足特定的需求,包括栈适配器(stack adapter)、队列适配器(queue adapter)和优先队列适配器(priority queue adapter)等。

容器

<array>: 定长数组容器

  • 基本语法:
std::array<T, N> array_name;

<vector>: 动态数组容器

  • 声明:
std::vector<int> myVector;
  • 访问元素:
int x = myVector[0]; // 获取第一个元素
int y = myVector.at(1); // 获取第二个元素
  • 添加元素:
myVector.push_back(10);
  • 删除元素:
myVector.pop_back();// 删除末尾元素myVector.erase(myVector.begin() + 2); // 根据迭代器删除指定元素
  • 迭代访问:
for (auto it = myVector.begin(); it != myVector.end(); ++it) {std::cout << *it << " ";
}
  • 清空:
myVector.clear(); // 清空 vector
  • 获取元素数量:
size_t size = myVector.size();
  • 判断是否为空:
myVector.empty();

<deque>: 双端队列容器

  • 声明:
std::deque<int> myDeque;
  • 访问元素:
myDeque[i];myDeque.at(i)
  • 返回第一个/最后一个元素的引用:
myDeque.front();myDeque.back();
  • 返回指向第一个/最后一个元素后一位置的迭代器:
myDeque.begin();myDeque.end();
  • 检查是否为空:
myDeque.empty();
  • 获取元素个数:
myDeque.size();
  • 添加元素:
myDeque.push_back(const T& value);// 队尾myDeque.push_front(const T& value);// 队头
  • 移除元素:
myDeque.pop_back();// 队尾myDeque.pop_front();// 队头erase(iterator pos);// 移除 pos 位置的元素
  • 清空:
myDeque.clear();
  • 调整容器大小:
myDeque.resize(size_type count);

<list>: 双向链表容器

  • 声明:
std::list<T> mylist;
  • 插入:
mylist.push_back(value);
  • 删除:
mylist.pop_back();mylist.erase(iterator);// 根据迭代器删除指定位置节点
  • 访问:
mylist.front();mylist.back();
  • 遍历:
for (auto it = mylist.begin(); it != mylist.end(); ++it){...
}

<forward_list>: 单向链表容器

  • std::forward_list 是单向链表,只能从前往后遍历,不能反向遍历;
  • 声明:
std::forward_list<int> fl;
  • 插入:
void push_front(const T& value);// 特别适合于需要在列表前端进行频繁插入和删除操作的场景
  • 移除:
void pop_front();
  • 返回迭代器:
iterator before_begin();// 返回指向列表前端之前的迭代器
iterator begin();// 返回指向列表前端的迭代器
iterator end();// 返回指向列表末尾的迭代器

<stack>: 栈容器适配器

  • <stack> 容器适配器提供了一个栈的接口,它基于其他容器(如 deque 或 vector)来实现;
  • 基本操作:
std::stack<int> s;// 声明push();// 在栈顶添加一个元素。
pop();// 移除栈顶元素。
top();// 返回栈顶元素的引用,但不移除它。
empty();// 检查栈是否为空。
size();// 返回栈中元素的数量。

<queue>: 队列容器适配器

  • 队列的实现通常使用链表或动态数组,这取决于具体的实现;
  • 基本操作:
// 声明队列
std::queue<Type> q;empty();// 检查队列是否为空。
size();// 返回队列中的元素数量。
front();// 返回队首元素的引用。
back();// 返回队尾元素的引用。
push();// 在队尾添加一个元素。
pop();// 移除队首元素。

<priority_queue>: 优先队列容器适配器

  • priority_queue 是一个容器适配器,优先队列是一种特殊的队列,它允许我们快速访问队列中具有最高(或最低)优先级的元素;
  • priority_queue 默认是一个最大堆;
  • 基本语法:
// 声明
priority_queue<int> pq;;empty();// 检查队列是否为空。
size();// 返回队列中的元素数量。
top();// 返回队列顶部的元素(不删除它)。
push();// 向队列添加一个元素。
pop();// 移除队列顶部的元素。
  • 自定义优先队列排序规则
// 声明一个自定义类型的优先队列,需要提供比较函数
struct compare {bool operator()(int a, int b) {return a > b; // 这里定义了最小堆}
};
priority_queue<int, vector<int>, compare> pq_min;
  • note:优先级队列的排序规则和其他排序规则如查找函数、set、map不同
    • 正常返回a>b指定为降序,而优先级队列会指定为升序;
    • 通常默认优先级队列为降序,而set、map默认为升序。

<set>: 集合容器(基于平衡二叉树)

  • 基于红黑树实现,特别适合需要快速查找、插入和删除操作的场景。
  • 基本语法:
// 声明一个整型 set 容器
std::set<int> mySet;insert(元素);// 插入一个元素。
erase(元素);// 删除一个元素。
find(元素);// 查找一个元素——返回迭代器,如果未找到返回 mySet.end()。
size();// 返回容器中元素的数量。
empty();// 检查容器是否为空。

<unordered_set>: 无序集合容器(基于哈希表)

  • unordered_set 不保证元素的排序,但通常提供更快的查找、插入和删除操作;
  • 基本语法:
// 声明
std::unordered_set<int> uset;insert(元素);// 插入一个元素。
erase(元素);// 删除一个元素。
find(元素);// 查找一个元素——返回迭代器,如果未找到返回 uset.end()。
size();// 返回容器中元素的数量。
empty();// 检查容器是否为空。
clear();// 清空。

<map>: 映射容器(键值对,基于平衡二叉树)

  • map用于存储键值对,单个元素可以看作为一个pair,一个map包含多个数对pair,因此for each遍历可以用pair取map的每个元素;
  • map 中的元素按照键的顺序自动排序,通常是升序;
  • 基本语法:
// 声明
std::map<key_type, value_type> myMap;// 插入元素
myMap[key] = value;// 访问元素
value = myMap[key];// 遍历map
for (std::map<key_type, value_type>::iterator it = myMap.begin(); it != myMap.end(); ++it) {std::cout << it->first << " => " << it->second << std::endl;
}// 检查键是否存在
if (myMap.find(key) != myMap.end()) {// 键存在
}// 删除元素
myMap.erase(key);// 清空map
myMap.clear();// 获取map大小
size_t size = myMap.size();

<unordered_map>: 无序映射容器(基于哈希表)

  • 基本语法:
// 声明
std::unordered_map<int, std::string> myMap;// 插入元素
myMap[key] = value;
myMap.insert({key, value});// 访问元素
value = myMap[key];// 遍历map
for (std::map<key_type, value_type>::iterator it = myMap.begin(); it != myMap.end(); ++it) {std::cout << it->first << " => " << it->second << std::endl;
}
for (const auto& pair : myMap) {std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
}// 检查键是否存在
if (myMap.find(key) != myMap.end()) {// 键存在
}// 删除元素
myMap.erase(key);

<bitset>: 二进制位容器

算法和迭代器

<algorithm>: 常用算法(如排序、查找等)

  • 基本语法:
algorithm_name(container.begin(), container.end(), ...);

排序

  • 基本语法:
sort(container.begin(), container.end(), compare_function);
  • 其中 compare_function 是一个可选的比较函数,用于自定义排序方式

搜索

  • 基本语法:
auto it = find(container.begin(), container.end(), value);

复制

  • 基本语法:
copy(source_begin, source_end, destination_begin);

比较

  • 基本语法:
bool result = equal(first1, last1, first2);// 或bool result = equal(first1, last1, first2, compare_function);

<iterator>: 迭代器

  • 迭代器是一个对象,它提供了一种方法来遍历容器中的元素。迭代器可以被视为指向容器中元素的指针,但它比指针更加灵活和强大。迭代器可以用于访问、修改容器中的元素,并且可以与 STL 算法一起使用。
  • 分类:
    • 输入迭代器(Input Iterator):只能进行单次读取操作,不能进行写入操作。
    • 输出迭代器(Output Iterator):只能进行单次写入操作,不能进行读取操作。
    • 正向迭代器(Forward Iterator):可以进行读取和写入操作,并且可以向前移动。
    • 双向迭代器(Bidirectional Iterator):除了可以进行正向迭代器的所有操作外,还可以向后移动。
    • 随机访问迭代器(Random Access Iterator):除了可以进行双向迭代器的所有操作外,还可以进行随机访问,例如通过下标访问元素。
  • 常用语法:
// 使用迭代器遍历容器
for (ContainerType::iterator it = container.begin(); it != container.end(); ++it) {// 访问元素 *it
}

函数对象和绑定

<functional>: 定义函数对象及相关工具

  • 函数对象是那些重载了 operator() 的对象,它们可以像普通函数一样被调用;
  • 常用的函数对象:
    • std::function:一个通用的多态函数封装器。
    • std::bind:用于绑定函数的参数。
    • std::plus、std::minus、std::multiplies、std::divides、std::modulus:基本的算术操作。
    • std::equal_to、std::not_equal_to、std::greater、std::less、std::greater_equal、std::less_equal:比较操作。
    • std::unary_negate、std::binary_negate:逻辑否定操作。
    • std::logical_and、std::logical_or、std::logical_not:逻辑操作。

字符串和正则表达式

<string>: 标准字符串类

  • 常用语法:
// 声明
std::string str;// 使用 + 连接字符串
std::string result = str1 + str2;// 常用成员函数
size();// 返回字符串的长度。empty();// 检查字符串是否为空。operator[];// 通过索引访问字符串中的字符。
at();// 访问字符串中指定位置的字符(带边界检查)substr();// 获取子字符串。
std::string sub = str.substr(0, 5);find();// 查找子字符串在主字符串中的位置。replace();// 替换字符串中的某些字符。
str.replace(pos, length, "new_substring");append();// 在字符串末尾添加内容
str.append(" more");insert();// 在指定位置插入内容。
str.insert(pos, "inserted");erase();// 删除指定位置的字符或子字符串。
str.erase(pos, length);clear();// 清空字符串。
str.clear();

<regex>: 正则表达式

  • 正则表达式的基本组成
    • 字符类:如 [abc] 表示匹配 a、b 或 c 中的任意一个字符。
    • 量词:如 *(零次或多次)、+(一次或多次)、?(零次或一次)。
    • 边界匹配:如 ^(行的开始)、$(行的结束)。
    • 分组:使用圆括号 () 来创建一个分组。

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

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

相关文章

IDEA 如何设置TAB页显示多行

前言 我们在使用IDEA开发时,经常需要打开多个TAB页,但是,IDEA默认的方式是最多只能打开少量的TAB页,且打开的TAB页只能堆积在一行上显示,如果超出了数量,就会自动隐藏。这样对于我能经常需要在多个不同TAB页之间打开来说,是比较麻烦的,那么有什么办法能改变下设置呢? …

在Linux下安装MySQL

摘要 在学习MySQL语法之前,我们需要先解决在Ubuntu或CentOs环境下的“软件安装”的问题。本文梳理了安装前后的各个步骤及有关的注意事项,主要涵盖了安装前的准备工作、如何安装mysql,以及安装之后如何启动、如何正式使用这几个方面。建议读者先浏览一遍,留心相关的注意事项…

深入剖析RocketMQ消息消费原理

本文参考转载至《RocketMQ技术内幕 第2版》一. 消息消费概述 消息消费以组的模式开展,一个消费组可以包含多个消费者,每个消费组可以订阅多个主题,消费组之间有集群模式和广播模式两种消费模式。集群模式是当前主题下的同一条消息只允许被其中一个消费者消费。广播模式是当前…

27. 守护进程、进程间通信

1. 僵尸进程与孤儿进程1.1 前言 在unix中,所有的子进程都是由父进程创建的,子进程再创建新的子进程 子进程的结束和父进程的运行是一个异步的过程,即子进程运行完成时,父进程并不知道 当子进程运行完成时,父进程需要调用wait()或waitpid()来获取子进程的运行状态 1.2 僵尸…

BUU XSS COURSE 1

启动靶机有留言板和登录功能,很明显是存储性xss,通过留言功能插入xss代码,获取cookie登录后台 先测试过滤 <script>alert(1);</script> 查看源代码发现script被过滤 <input onfocus="alert(xss);">好像只过滤了script找一个xss平台或者自己用服…

Wireshark开源抓包工具

Wireshark零基础使用教程(超详细) - 元宇宙-Metaverse - 博客园 (cnblogs.com)一、Wireshark是什么 Wireshark是使用最广泛的一款「开源抓包软件」,常用来检测网络问题、攻击溯源、或者分析底层通信机制。 它使用WinPCAP作为接口,直接与网卡进行数据报文交换。 二、Wiresha…

Prompt提示词概念

什么是prompt提示词? 叮!快来看看我和文心一言的奇妙对话~什么是提示工程(prompt engineering)?点击链接 https://yiyan.baidu.com/share/vMZ69XCFTc?utm_invite_code=P0HSh4T14mrU4TwxGbJ%2BSw%3D%3D&utm_name=SGlkZGVuX3N0YXJz&utm_fission_type=common -- 文心…

C#|.net core 基础 - 深拷贝的五大类N种实现方式

C#深拷贝复杂,文中介绍了五大类N种深拷贝方法,包括简单引用类型、手动方式、序列化方式、第三方库方式和扩展视野方式,并对比了性能。建议使用AutoMapper和DeepCloner等成熟库或根据性能需求选择表达式树和Emit。在实际应用中经常会有这样的需求:获取一个与原对象数据相同但…