【C++ 语言】容器 ( queue 队列 | stack 栈 | priority_queue 优先级队列 | set 集合 | 容器遍历 | map )(三)

简介: 【C++ 语言】容器 ( queue 队列 | stack 栈 | priority_queue 优先级队列 | set 集合 | 容器遍历 | map )(三)

容器遍历


迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ;


1. 迭代器使用 : 迭代器是一个模板类 ;


2. 获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器


vector<int> vector_iterator = {8 , 88 , 888};
  //该迭代器指向容器中第 0 个元素
  vector<int>::iterator iterator_begin = vector_iterator.begin();
  //迭代器指向容器中最后一个元素的下一个元素 , 
  //  注意 : 不是指向最后一个元素
  vector<int>::iterator iterator_end = vector_iterator.end();


3. 使用迭代器进行遍历 , 打印 vector 中的元素;


for ( ; iterator_begin < iterator_end; iterator_begin ++ ) {
  cout << "迭代器遍历 : " << *iterator_begin << endl;
  }


4. 代码示例 :


// VII . 容器的遍历
  //迭代器使用 : 迭代器是一个模板类 
  //获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器
  vector<int> vector_iterator = {8 , 88 , 888};
  //该迭代器指向容器中第 0 个元素
  vector<int>::iterator iterator_begin = vector_iterator.begin();
  //迭代器指向容器中最后一个元素的下一个元素 , 
  //  注意 : 不是指向最后一个元素
  vector<int>::iterator iterator_end = vector_iterator.end();
  //使用迭代器进行遍历 , 打印 vector 中的元素
  for ( ; iterator_begin < iterator_end; iterator_begin ++ ) {
  cout << "迭代器遍历 : " << *iterator_begin << endl;
  }
  //循环时尽量不修改容器大小 : 遍历时不能进行删除增加操作 , 否则会出错 ; 
  //如果循环时修改大小 : 要根据实际情况进行操作 , 如删除操作 , 
  //  如果将本元素删除 , 那么循环控制变量就不能自增
  //迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ;


5. 执行结果 :


迭代器遍历 : 8
迭代器遍历 : 88
迭代器遍历 : 888



map 映射


1. 包含头文件 :


//引入 map 的头文件
#include <map>


2. map 特点 : map 中不能存在重复的 key ;


3. 声明 map : 直接初始化元素 ;


//声明 map 时 , 直接初始化元素
  map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} };


4. 插入键值对 :


//插入一个键值对
  map_student.insert({ "Trump" , 70 });


5. 访问对应键值对 :


//获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值 
  map_student["Tom"] = 18;


6. 代码示例 :


// VIII . map 集合
  //map 中不能存在重复的 key ; 
  //声明 map 时 , 直接初始化元素
  map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} };
  //插入一个键值对
  map_student.insert({ "Trump" , 70 });
  //获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值 
  map_student["Tom"] = 18;
  cout << "map_student[\"Tom\"] : " << map_student["Tom"] << endl;


7. 执行结果 :


map_student["Tom"] : 18




容器代码示例


1. 容器代码示例 :


// 004_Container.cpp: 定义应用程序的入口点。
//
#include "004_Container.h"
//vector 是 C++ 中定义的模板类 
#include <vector>
//引入队列头文件 , 才能使用 queue 队列
//queue 队列 , 也是 STL 模板类中提供的容器
#include <queue>
//引入 stack 栈的头文件
#include <stack>
//引入 set 集合的头文件
#include <set>
//引入 map 的头文件
#include <map>
using namespace std;
//自定义容器
class Student {
public :
  int age; 
  //声明构造方法 , 后面的 : age(age) 
  //  左侧的 age 表示给 age 成员赋值 , 右边的表示参数中的 age 值
  Student(int age) : age(age){}
};
// Student 类对象排序方法定义
//  排序方式 : 左侧对象的 age 成员变量 , 大于右侧对象的 age 成员变量
struct StudentLess { 
  constexpr bool operator()(const Student& _Left, const Student& _Right) const { 
  return _Left.age < _Right.age;
  }
};
int main()
{
  cout << "Hello Container。" << endl;
  // I . vector 向量 ( vector , dequeue , list 调用方式基本一致 )
  //vector 向量是一种支持快速随机访问的 , 连续存储元素的容器
  //声明向量
  vector<int> vector_1;
  //调用向量的构造方法 , 并传入一个 int 类型参数
  //表示创建一个有 8 个 int 类型元素空间的向量
  vector<int> vector_2(8);
  //表示创建有 8 个元素的向量 , 8 个元素的值都是 2
  vector<int> vector_3(8 , 2);
  //初始化向量时 , 传入另一个向量
  vector<int> vector_4(vector_3);
  // 2. 使用向量 : 增删查改
  // ( 1 ) 增加元素 : 调用 push_back 方法 , 容器出入策略 , 后进先出
  vector_1.push_back(8);
  vector_1.push_back(88);
  // ( 2 ) 查询元素 : 
  // <1> 通过下标获取元素
  //  这里的 [] 在 vector 中进行了运算符重载
  cout << "通过下标获取 vector_1 第 0 个元素 : vector_1[0] : " << vector_1[0] << endl;
  // <2> 通过 at() 方法获取对应索引的元素
  cout << "通过 at 方法获取 vector_1 第 0 个元素 : vector_1.at(0) : " << vector_1.at(0) << endl;
  // <3> 获取第一个元素
  cout << "通过 front 方法获取 vector_1 第 1 个元素 : vector_1.front() : " << vector_1.front() << endl;
  // <4> 获取最后一个元素
  cout << "通过 back 方法获取 vector_1 最后 1 个元素 : vector_1.back() : " << vector_1.back() << endl;
  // ( 4 ) 删除元素 : 
  // <1> 调用 pop_back 方法 , 容器出入策略 , 后进先出
  vector_1.pop_back();
  //之前向 vector 中先后放入了 8 和 88 两个数 , 
  //  然后删除了后一个元素 88 , 目前只剩下一个元素 8
  // <2> 删除所有元素 , 这里只是清空元素内容为 0
  vector_1.clear();
  // <3> 删除指定位置区间的元素 , 这里只是清空元素内容为 0
  //  第 1 个是删除的起始位置 , 
  //  第 2 个参数是删除的结束位置 ;
  //删除从开始到结束的所有元素
  vector_1.erase(vector_1.begin() , vector_1.end());
  //关于删除元素内存说明 : 
  //  删除若干元素后 , vector 的容量 , 即内存所占的空间是不会减小的 ; 
  //  调用删除方法后 , 就不能在查询上述元素了
  //打印 vector 容器容量大小 , 调用 vector 的 capacity() 方法即可获取其容量大小
  //  这个容量大小是元素个数 , 不是内存字节数
  cout << "打印 vector_1 容量大小 : vector_1.capacity() : " << vector_1.capacity() << endl;
  // ( 5 ) 改变容量 , 容器交换 , 这里使用一个容量为 0 的容器与之交换即可
  //创建一个新的 vector , 此时其容量为 0
  vector<int> vector_swap;
  //将创建的新的 vector_swap 与 vector_1 容器进行交换
  vector_swap.swap(vector_1);
  cout << "打印 vector_1 交换后的容量大小 : vector_1.capacity() : " << vector_1.capacity() << endl;
  // II . queue 队列
  //队列是一个先进先出的容器
  //声明队列
  queue<int> queue_1;
  //添加元素到队列中 
  queue_1.push(8);
  queue_1.push(88);
  //将元素弹出队列
  queue_1.pop(); 
  //获取首尾元素
  queue_1.front();
  queue_1.back();
  // III . stack 栈
  //stack 栈 是后进先出的容器
  stack<int> stack_1;
  // IV . priority_queue 优先级队列
  //声明优先级队列
  priority_queue<int> pq;
  //其默认复制数值最大的在队首 
  pq.push(88);
  pq.push(8);
  pq.push(888);
  //获取队首元素 , 将其打印出来 , 应该是将最大的 888 打印到了控制台
  //虽然 888 是最后添加进去的 , 但是其数值最大 , 被放在了首元素位置 
  int pq_top = pq.top();
  cout << "打印 priority_queue 优先级队列的首元素 : pq.top() : " << pq.top() << endl;
  //指定优先级队列最大值放在队尾
  //参数 1 : 代表队列中元素的类型是 int 类型
  //参数 2 : 代表优先级队列使用的内部容器 , 整个队列是基于 vector 容器的
  //参数 3 : 设置排序行为 , 这个行为是在 STL 中定义的模板类 
  //    less<int> : 是默认行为 , 最大的元素在前面
  //    greater<int> : 最小的在前面
  priority_queue< int, vector<int> , greater<int> > pq_1;
  pq_1.push(88);
  pq_1.push(8);
  pq_1.push(888);
  cout << "打印 pq_1 优先级队列的首元素 : pq.top() : " << pq_1.top() << endl;
  //自定义类型容器队列
  //  注意此处必须指定 Student 对象之间的排序方式 , 否则编译时会报错 
  //  可以参考 less 和 greater 的实现
  //自定义的排序方法 : StudentLess , 其会将 Student 对象的 age 成员变量大的排在前面
  priority_queue< Student, vector<Student>, StudentLess > pq_student;
  //向自定义类型容器队列中加入 3 个对象 , 使用构造函数生成对象
  pq_student.push(Student(8));
  pq_student.push(Student(18));
  pq_student.push(Student(15));
  cout << "打印 pq_student 优先级队列的首元素 : pq_student.top().age : " << pq_student.top().age << endl;
  // V . 关联式容器
  //操作 : 关联式容器的操作 , 与序列式容器调用方法基本一致
  //访问方式 : 通过关键字保存和访问元素 , 如 Java 中的 Map , Set  ; 
  // VI . set 集合
  //  Set : 集合 , 内部是由红黑树实现的 , 每个节点都是一个元素 , 其元素不可重复
  set<int> set_1 = {8 , 888 , 8888};
  //插入 18 , 集合中没有元素 18 , 此时插入成功
  set_1.insert(18);
  //插入 888 , 此时之前已经有了 888 元素 , set 集合不允许重复 , 本次插入失败
  set_1.insert(888);
  //insert 返回值是一个键值对 , 其键是一个迭代器 ,
  //  值是 bool 类型 , 如果插入成功值为 true , 否则为 false
  //  返回值类型 : pair<iterator, bool>
  //  具体的返回值类型 : pair<set<int>::iterator, bool>
  //删除某个元素
  set_1.erase(888); 
  //打印容器大小
  cout << "打印 set_1 删除 888 容量大小 : set_1.size() : " << set_1.size() << endl;
  // VII . 容器的遍历
  //迭代器使用 : 迭代器是一个模板类 
  //获取迭代器 : 调用 vector 对象的 begin() 和 end() 方法 都可获取迭代器
  vector<int> vector_iterator = {8 , 88 , 888};
  //该迭代器指向容器中第 0 个元素
  vector<int>::iterator iterator_begin = vector_iterator.begin();
  //迭代器指向容器中最后一个元素的下一个元素 , 
  //  注意 : 不是指向最后一个元素
  vector<int>::iterator iterator_end = vector_iterator.end();
  //使用迭代器进行遍历 , 打印 vector 中的元素
  for ( ; iterator_begin < iterator_end; iterator_begin ++ ) {
  cout << "迭代器遍历 : " << *iterator_begin << endl;
  }
  //循环时尽量不修改容器大小 : 遍历时不能进行删除增加操作 , 否则会出错 ; 
  //如果循环时修改大小 : 要根据实际情况进行操作 , 如删除操作 , 
  //  如果将本元素删除 , 那么循环控制变量就不能自增
  /*
  vector<int> vector_iterator_delete = { 8 , 88 , 888 };
  vector<int>::iterator iterator_begin_delete = vector_iterator_delete.begin();
  vector<int>::iterator iterator_end_delete = vector_iterator_delete.end();
  //遍历时删除元素 : 使用迭代器进行遍历 , 打印 vector 中的元素 , 遇到 888 元素 , 将其删除
  for (; iterator_begin_delete < iterator_end_delete; iterator_begin_delete ++ ) {
  if (*iterator_begin_delete == 888) {
    cout << "迭代器遍历删除 ( 本次遍历删除该元素 ) : " << *iterator_begin_delete << endl;
    //如果元素值为 888 , 那么删除该元素
    //iterator_begin_delete = vector_iterator_delete.erase(iterator_begin_delete);
    //iterator_begin_delete--;
  }else {
    cout << "迭代器遍历删除 ( 本次遍历没有删除 ) : " << *iterator_begin_delete << endl;
  }
  }
  */
  //迭代器不是指针 , 是一个模板类 , 与指针行为一致 , 可以当做指针来用 ; 
  // VIII . map 集合
  //map 中不能存在重复的 key ; 
  //声明 map 时 , 直接初始化元素
  map<string, int> map_student = { {"Tom" , 6} , {"Jerry" , 2} };
  //插入一个键值对
  map_student.insert({ "Trump" , 70 });
  //获取对应键的值 , 使用 map变量名称[键] 可以获取对应的值 
  map_student["Tom"] = 18;
  cout << "map_student[\"Tom\"] : " << map_student["Tom"] << endl;
  return 0;
}




2. 执行结果 :


Hello Container。
通过下标获取 vector_1 第 0 个元素 : vector_1[0] : 8
通过 at 方法获取 vector_1 第 0 个元素 : vector_1.at(0) : 8
通过 front 方法获取 vector_1 第 1 个元素 : vector_1.front() : 8
通过 back 方法获取 vector_1 最后 1 个元素 : vector_1.back() : 88
打印 vector_1 容量大小 : vector_1.capacity() : 2
打印 vector_1 交换后的容量大小 : vector_1.capacity() : 0
打印 priority_queue 优先级队列的首元素 : pq.top() : 888
打印 pq_1 优先级队列的首元素 : pq.top() : 8
打印 pq_student 优先级队列的首元素 : pq_student.top().age : 18
打印 set_1 删除 888 容量大小 : set_1.size() : 3
迭代器遍历 : 8
迭代器遍历 : 88
迭代器遍历 : 888
map_student["Tom"] : 18


目录
相关文章
|
9月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
500 2
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
735 1
|
存储 负载均衡 算法
基于 C++ 语言的迪杰斯特拉算法在局域网计算机管理中的应用剖析
在局域网计算机管理中,迪杰斯特拉算法用于优化网络路径、分配资源和定位故障节点,确保高效稳定的网络环境。该算法通过计算最短路径,提升数据传输速率与稳定性,实现负载均衡并快速排除故障。C++代码示例展示了其在网络模拟中的应用,为企业信息化建设提供有力支持。
423 15
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
409 2
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
829 156
|
9月前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。
|
11月前
|
存储 C++
C++语言中指针变量int和取值操作ptr详细说明。
总结起来,在 C++ 中正确理解和运用 int 类型地址及其相关取值、设定等操纵至关重要且基础性强:定义 int 类型 pointer 需加星号;初始化 pointer 需配合 & 取址;读写 pointer 执向之处需配合 * 解引用操纵进行。
781 12
|
存储 算法 安全
企业员工数据泄露防范策略:基于 C++ 语言的布隆过滤器算法剖析[如何防止员工泄密]
企业运营过程中,防范员工泄密是信息安全领域的核心议题。员工泄密可能致使企业核心数据、商业机密等关键资产的流失,进而给企业造成严重损失。为应对这一挑战,借助恰当的数据结构与算法成为强化信息防护的有效路径。本文专注于 C++ 语言中的布隆过滤器算法,深入探究其在防范员工泄密场景中的应用。
330 8
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
734 0