首页 > 编程语言 >C++ STL标准模板库使用

C++ STL标准模板库使用

时间:2023-03-14 21:23:32浏览次数:55  
标签:std map STL 元素 list C++ vector myMap 模板

C++ STL标准模板库使用

在线手册参考

C++ STL(标准模板库)是一组标准的 C++ 库,包含了许多常用的数据结构和算法,可大大提高开发效率。以下是常用的 STL 组件:

  1. 容器(Containers):用于存储和管理数据的类模板。常用的容器有:
  • vector:动态数组
  • list:双向链表
  • deque:双端队列
  • set/multiset:集合/多重集合,内部自动排序
  • map/multimap:映射/多重映射,内部自动排序
  • stack:栈
  • queue:队列
  1. 迭代器(Iterators):用于遍历容器中的元素,支持类似指针的操作。
  2. 算法(Algorithms):用于处理容器中的元素,包括查找、排序、删除、替换等。
  3. 函数对象(Function Objects):可用于在算法中进行自定义操作的函数对象。
  4. 数值(Numeric):包含一些数学函数和算法,如求和、平均数、中位数等。
  5. 适配器(Adapters):用于将一种容器或迭代器适配成另一种容器或迭代器,常用的适配器有:
  • stack:用于将 deque 或 list 适配成栈
  • queue:用于将 deque 或 list 适配成队列
  • priority_queue:用于将 vector 或 deque 适配成优先队列

vector

在 C++ STL 中,vector 是一个动态数组容器,它可以自动调整大小以适应元素数量的变化。

常用操作如下:

创建

#include <vector>

// 创建一个空的 vector
std::vector<int> vec;

// 创建一个含有 10 个元素,每个元素都是 0 的 vector
std::vector<int> vec1(10);

// 创建一个含有 10 个元素,每个元素都是 1 的 vector
std::vector<int> vec2(10, 1);

// 创建一个含有 3 个元素,值分别是 1,2,3 的 vector
std::vector<int> vec3 = {1, 2, 3};

// 使用迭代器创建 vector
std::vector<int> vec4(vec3.begin(), vec3.end());

注意:也可以在堆创建vector,不过会比在栈存取数据慢些

vector<int> *vec = new vector<int>{1,2,3};

std::vector<int> vec = {1, 2, 3};

// 在末尾添加一个元素 4
vec.push_back(4);

// 在位置 1 处插入元素 5
vec.insert(vec.begin() + 1, 5);

// 在末尾插入另一个 vector 的所有元素
std::vector<int> vec2 = {6, 7, 8};
vec.insert(vec.end(), vec2.begin(), vec2.end());

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

// 删除末尾的元素
vec.pop_back();

// 删除位置 2 的元素
vec.erase(vec.begin() + 2);

// 删除位置 1 到 3 的元素
vec.erase(vec.begin()+1, vec.begin()+4);

改/查

使用 [] 运算符和 at() 方法都可以访问 vector 中的元素,不同之处在于:

  • 如果使用 [] 运算符访问超出 vector 范围的元素,程序将出现未定义行为

  • 而使用 at() 方法访问超出 vector 范围的元素,程序将抛出 std::out_of_range 异常。

vec[2] // 访问第2个元素
vec.at(3) // 访问第3个元素

vec[2] = 1 // 修改第2个元素值为1
vec.at(3) = 1 // 修改第3个元素值为1

或者使用迭代器访问、修改

vector<int> vec{1, 2, 3, 4, 5};

// 使用迭代器遍历 vector 中的元素
for (auto it = vec.begin(); it != vec.end(); ++it) {
    cout << *it << " ";
}
// 使用迭代器修改 vector 中的元素
for (auto it = vec.begin(); it != vec.end(); ++it) {
    *it += 1;
}
// 使用范围 for 循环输出修改后的 vector 中的元素
for (auto x : vec) {
    cout << x << " ";
}

list

C++ STL 中的 list 是一个双向链表,可以在任意位置进行插入和删除操作,而不会影响其他元素的位置。以下是 list 的常用用法

创建

#include <list>

std::list<int> myList; // 创建一个空的 list
std::list<int> myList = {1, 2, 3, 4, 5}; // 创建包含 1, 2, 3, 4, 5 的 list

  • push_back(value):在 list 尾部插入一个元素。
  • push_front(value):在 list 头部插入一个元素。
  • insert(pos, value):在指定位置插入一个元素。

  • erase(pos):删除指定位置的元素。
  • erase(start, end):删除从 start 到 end 之间的元素。

示例代码:

#include <list>
#include <iostream>

int main() {
    std::list<int> myList = {1, 2, 3};
    myList.push_back(4); // 在尾部插入 4
    myList.push_front(0); // 在头部插入 0
    myList.insert(++myList.begin(), 5); // 在第二个位置插入 5
    myList.erase(--myList.end()); // 删除最后一个元素
    myList.erase(myList.begin(), myList.begin() + 2); // 删除前两个元素

    for (int i : myList) {
        std::cout << i << " "; // 输出: 2 5 4
    }
    return 0;
}

改/查

可以使用以下方法访问 list 中的元素:

  • front():返回 list 的第一个元素。
  • back():返回 list 的最后一个元素。

迭代器法:

// 使用迭代器遍历 list 中的元素
for (auto it = lst.begin(); it != lst.end(); ++it) {
    cout << *it << " ";
}
cout << endl;

// 使用迭代器修改 list 中的元素
for (auto it = lst.begin(); it != lst.end(); ++it) {
    *it += 1;
}

// 使用范围 for 循环输出修改后的 list 中的元素
for (auto x : lst) {
    cout << x << " ";
}

list不能像 vector 那样使用索引或 at() 方法来访问和修改元素,只能通过迭代器来完成。

此外,由于 std::list 的迭代器不支持随机访问,因此不能使用 [] 运算符来访问元素。

其它

除了上述操作,list 还支持以下操作:

  • size():返回 list 中元素的个数。
  • empty():判断 list 是否为空。
  • clear():清空 list 中的元素。
  • sort():将 list 中的元素进行排序。

queue

std::queue 是 STL 中的队列容器,它可以用来存储一系列具有相同数据类型的元素,并支持队列的基本操作,如入队、出队、获取队首元素等。下面是 std::queue 的常用用法

创建

std::queue<int> q;  // 创建一个空队列,元素类型为 int

增/删

q.push(2); //插入元素1到队列尾部
q.pop();  // 从队列头部弹出元素

改(X)/查(√)

可以使用 front() 成员函数来获取队列的头部元素,但是需要注意,在调用该函数之前必须先判断队列是否为空

// 获取队列的头部元素
if (!q.empty()) {
    cout << "Front element: " << q.front() << endl;
}

不支持直接修改队列内部元素,也不支持直接获取尾部元素

其它

q.empty();  // 判断是否队列为空
q.size();   // 获取队列内元素个数

stack

std::stack 是 C++ 标准库中的一个容器适配器,它提供了一个 LIFO(后进先出)的数据结构。std::stack 支持以下基本操作:

创建

#include <stack>
stack<int> s; // 创建栈s

增删

s.push(1);  // 元素1从栈顶入栈
s.pop();	// 弹出出栈顶元素

改(X)/查(√)

s.top();  // 获取栈顶元素

不支持修改栈内元素

其它

s.size(); // 获取栈内元素个数
s.empty(); // 判断栈是否为空。

map

C++ 中的 map 是一种关联容器(associative container),用于存储键值对。在 map 中,每个键唯一且与一个值相关联。

map底层是红黑树,是有序的

以下是一些常用的 map 操作

创建

#include <map>

std::map<std::string, int> myMap;  // 创建一个空 map,键类型为 string,值类型为 int

// 创建并初始化一个 map
std::map<std::string, int> myMap2 = {{"apple", 1}, {"banana", 2}, {"orange", 3}};

增删

myMap["key"] = value;  // 插入键值对
myMap.insert(key, value)
myMap.erase(key);  // 删除键为 key 的元素
myMap.clear();  // 删除所有元素

改/查

myMap["key"] = value;  // 改(已经存在key的时候是修改)
int value = myMap["key"];  // 访问键对应的值

// 检查是否存在某个键
if (myMap.find("key") != myMap.end()) {
  // 执行操作
}

迭代器

// 使用迭代器遍历 map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
  std::cout << it->first << " => " << it->second << '\n';
}

// 使用范围遍历语句遍历 map
for (const auto& [key, value] : myMap) {
  std::cout << key << " => " << value << '\n';
}

其他

count(key) 判断是否存在键为key的元素,存在返回1,否则返回0

std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"orange", 3}};

if (myMap.count("apple")) {
  std::cout << "apple exists in myMap.\n";
} else {
  std::cout << "apple does not exist in myMap.\n";
}
empty(); //是否为空
size();  // 键值对个数

find(key) 函数用于查找键为 key 的元素,如果找到了,则返回一个指向该元素的迭代器,否则返回 map 的尾部迭代器

std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}, {"orange", 3}};

auto it = myMap.find("apple");
if (it != myMap.end()) {
  std::cout << "apple found in myMap with value " << it->second << '\n';
} else {
  std::cout << "apple not found in myMap.\n";
}

unordered_map

C++ 中的 unordered_map 是一种关联容器(associative container),与 map 类似,也用于存储键值对。

不同之处在于,unordered_map 不保证元素的顺序,并使用哈希表来实现快速查找。

unordered_map 一些操作与map基本相同

需要注意的是,unordered_map 的查询操作通常比 map 更快,但存储的元素顺序是不确定的。因此,当需要对元素进行有序访问时,应该使用 map

创建

#include <unordered_map>

std::unordered_map<std::string, int> myMap;  // 创建一个空 unordered_map,键类型为 string,值类型为 int

// 创建并初始化一个 unordered_map
std::unordered_map<std::string, int> myMap2 = {{"apple", 1}, {"banana", 2}, {"orange", 3}};

增删

myMap["key"] = value;  // 插入键值对

myMap.erase(key);  // 删除键为 key 的元素
myMap.clear();  // 删除所有元素

改/查

myMap["key"] = value;  // 修改键key的值
int value = myMap["key"];  // 访问键对应的值

// 检查是否存在某个键
if (myMap.find("key") != myMap.end()) {
  // 执行操作
}

迭代器

// 使用迭代器遍历 unordered_map
for (auto it = myMap.begin(); it != myMap.end(); ++it) {
  std::cout << it->first << " => " << it->second << '\n';
}

// 使用范围遍历语句遍历 unordered_map
for (const auto& [key, value] : myMap) {
  std::cout << key << " => " << value << '\n';
}

标签:std,map,STL,元素,list,C++,vector,myMap,模板
From: https://www.cnblogs.com/ajream/p/17216451.html

相关文章

  • 2816. 判断子序列(双指针模板题)
    https://www.acwing.com/problem/content/2818/双指针模板题:i指针只有匹配到相等才++,j指针无论如何每次都++那么i==n时,意味着b序列中存在着a序列,且有序离散存放#inclu......
  • c++ noexcept与constexpr解析
    文章目录​​1.noexcept无需抛出异常​​​​2.constexpr静态编译关键字​​​​编译期常量​​​​类中constexpr​​1.noexcept无需抛出异常在C++中使用noexcept来标识......
  • C++ 哈希表的总结与例题
    文章目录​​C++STL​​​​哈希表​​​​设计哈希集合​​​​设计哈希映射​​​​哈希集合​​​​例题一:只出现一次的数字​​​​例题二:快乐数​​​​哈希映射​​​......
  • 以下是一个使用C++实现HTTP文件下载的简单示例,其中使用了C++ 11的标准库和Boost库:
    #include<iostream>#include<fstream>#include<boost/asio.hpp>usingboost::asio::ip::tcp;intmain(){try{boost::asio::io_serviceio_se......
  • C++ 基础部分 个人笔记
    本人菜鸟,个人学习笔记,如有错误还请指教C++模板是什么C++模板是一种基于类型参数化的编程技术,使用模板可以使得程序员编写独立于具体数据类型的通用代码。通过参数化类......
  • Docker - 部署抓包/host代理工具 Whistle
    编写DockerfileFROMalpineEXPOSE8899RUNapkadd--no-cachenodejsnpm\&&npminstallwhistle-g\&&apkdelnpm\&&mkdir/whistleENTRYPOI......
  • C++_一些重要的编译参数
    1.-g编译带调试信息的可执行文件#-g告诉g++产生可供GDB使用的调试信息。g++-gtest.cpp-otest2.-O[n]优化源代码-O:同时减小代码的长度和执行时间,其效果等价于......
  • 【多线程】C++11多线程(简约但不简单) 原创
    【多线程】C++11多线程(简约但不简单) 目录​ ​一、简单使用​​​ ​1、线程参数​​​ ​2.类成员函数做为线程入口​​​ ​3.join:等待线程执......
  • C/C++班级成绩管理系统[2023-03-13]
    C/C++班级成绩管理系统[2023-03-13]4.5班级成绩管理系统题目描述对一个有N个(>=10)学生的班级,每个学生有M门(>=5)课程。该系统实现对班级成绩的录入、显示、修改、排序......
  • c/c++指针从浅入深介绍——基于数据内存分配的理解(上)
    c/c++指针从浅入深介绍——基于数据内存分配的理解(上)本文是对自我学习的一个总结以及回顾,文章内容主要是针对代码中的数据在内存中的存储情况以及存储中数值的变化来......