C++ set、map

文章目录

  • 关联式容器
  • 键值对
  • 树形结构的关联式容器
  • set
    • set的介绍
    • set的使用
  • multiset
  • map
    • map的介绍
    • map的使用
  • multimap

关联式容器

C++STL包含了序列式容器和关联式容器:

  1. 序列式容器:vector/list/deque
  2. 关联式容器:set/map等

关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。

键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。
比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应
该单词,在词典中就可以找到与其对应的中文含义。
SGI-STL中关于键值对的定义:

template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}
};

树形结构的关联式容器

根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。
树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。unordered系列均为哈希结构。

set

set的介绍

  1. set是按照一定次序存储元素的容器。
  2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的。

set的使用

#include <iostream>
#include <set>
using namespace std;int main()
{//插入元素(去重且排序)set<int> s; // 默认是升序// set<int, greater<int>> s; // 这样是降序s.insert(4);s.insert(4);s.insert(1);s.insert(3);s.insert(6);s.insert(6);// 迭代器遍历set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";*it++;}cout << endl;// 范围for遍历for (auto e : s){cout << e << " ";}cout << endl;// 删除3 (存在)s.erase(3);// 删除4set<int>::iterator pos = s.find(4);if (pos != s.end()){s.erase(pos);}// s.erase(100); // 删除不存在的值没有影响// s.erase(s.end()); 会崩掉for (auto e : s){cout << e << " ";}cout << endl;//容器中值为4的元素个数cout << s.count(6) << endl; // 1//容器大小cout << s.size() << endl; // 4//清空容器s.clear();//容器判空cout << s.empty() << endl; // 1return 0;
}

multiset

multiset容器与set容器的底层实现一样,都是平衡搜索树(红黑树);
multiset容器和set容器的唯一区别就是multiset容器当中存储的元素是可以重复的。

#include <iostream>
#include <set>
using namespace std;int main()
{// 查找在不在// 插入元素(重复且排序)multiset<int> ms;ms.insert(1);ms.insert(2);ms.insert(3);ms.insert(3);ms.insert(2);ms.insert(3);for (auto e : ms){cout << e << " ";}cout << endl; //1 2 2 3 3 3 4return 0;
}

multiset

  • find():返回第一个中序的第一个val
  • count():返回值为val的元素个数

set

  • find():返回值为val的元素的迭代器l
  • count():值为val的元素存在则返回1,不存在则返回0

map

map的介绍

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:typedef pair<const key, T> value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序的。
  4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

map的使用

#include <iostream>
#include <map>using namespace std;int main()
{map<string, string> m;// 构造匿名对象插入m.insert(pair<string, string>("left", "左边"));m.insert(pair<string, string>("right", "右边"));m.insert(pair<const char*, const char*>("up", "上边"));// 调用make_pair函数模板插入// 我们只需向make_pair函数传入key和value,// 该函数模板会根据传入参数类型进行自动隐式推导,// 最终构造并返回一个对应的pair对象。m.insert(make_pair("down", "下边")); // 推荐这个最优(能省即省,能少敲就少敲,qwq)// 迭代器遍历map<string, string>::iterator it = m.begin();while (it != m.end()){cout << "<" << (*it).first << "," << (*it).second << ">" ;// it.operatot()  返回 *pair// cout << "<" << it.operator->()->first << "," << it.operator->()->second << ">";cout << "<" << it->first << "," << it->second << ">" ;cout << endl;++it;}cout << endl;// 范围for遍历for (auto e : m){cout << "<" << e.first << "," << e.second << ">";cout << endl;}cout << endl;// pair里的 key有const,而value没有constfor (auto& e : m){e.first += '1'; // 不可修改e.second += '1'; // 可修改 cout << "<" << e.first << "," << e.second << ">";cout << endl;}cout << endl;return 0;
}

make_pair函数模板:

template <class T1, class T2>
pair<T1, T2> make_pair(T1 x, T2 y)
{return (pair<T1, T2>(x, y));
}

insert的返回值

insert函数的返回值也是一个pair对象,该pair对象中第一个成员的类型是map的迭代器类型,第二个成员的类型的一个bool类型,具体含义如下:

  1. 若待插入元素的键值key在map当中不存在,则insert函数插入成功,并返回插入后元素的迭代器和true。
  2. 若待插入元素的键值key在map当中已经存在,则insert函数插入失败,并返回map当中键值为key的元素的迭代器和false。

map的[ ]

mapped_type& operator[] (const key_type& k);

[ ]运算符重载实现的逻辑实际上就是以下三个步骤:

  • 调用insert函数插入键值对。
  • 拿出从insert函数获取到的迭代器。
  • 返回该迭代器位置元素的值value。
mapped_type& operator[] (const key_type& k)
{//1、调用insert函数插入键值对pair<iterator, bool> ret = insert(make_pair(k, mapped_type()));//2、拿出从insert函数获取到的迭代器iterator it = ret.first;//3、返回该迭代器位置元素的值valuereturn it->second;
}
  • 如果k不在map中,则先插入键值对<k, v()>,然后返回该键值对中v对象的引用。
  • 如果k已经在map中,则返回键值为k的元素对应的v对象的引用。
#include <iostream>
#include <map>using namespace std;int main()
{string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };map<string, int> countMap;for (auto& str : arr){//auto ret = countMap.find(str);//if (ret == countMap.end())//{//	// 么有表示第一次出现,插入//	countMap.insert(make_pair(str, 1));//}//else//{//	// 次数++//	ret->second++;//}countMap[str]++; // 6 3 2}for (auto& str : arr){countMap[str]++; // 12 6 4}for (auto& kv : countMap){cout << kv.first << ":" << kv.second << endl;}return 0;
}

multimap

multimap容器与map容器的底层实现一样,也都是平衡搜索树(红黑树);
multimap容器和map容器的区别与multiset容器和set容器的区别一样,multimap容器当中存储的元素是可以重复的。

#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{multimap<string, string> mm;//插入元素(重复且排序)mm.insert(make_pair("left", "左边"));mm.insert(make_pair("left", "左边"));mm.insert(make_pair("right", "右边"));mm.insert(make_pair("up", "上边"));mm.insert(make_pair("left", "左边"));mm.insert(make_pair("right", "右边"));mm.insert(make_pair("up", "上边"));for (auto e : mm){cout << "<" << e.first << "," << e.second << ">";cout << endl;}cout << endl; return 0;
}

multimap

  • find():返回底层搜索树中序的第一个键值为key的元素的迭代器
  • count():返回键值为key的元素个数

map

  • find():返回值为key的元素的迭代器
  • count():键值为key的元素存在则返回1,不存在则返回0

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

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

相关文章

Java基础:设计模式之抽象工厂模式

一、模式定义与目的 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它为创建一组相关或相互依赖的对象提供了接口&#xff0c;而无需指定这些对象的具体类。这种模式允许客户端使用抽象接口来创建家族内的产品对象&#xff0…

Yolov5 export.py实现onnx模型的导出

查了很多资料&#xff0c;很多用python代码写的&#xff0c;只需要这个库那个库的&#xff0c;最后都没成功。 不如直接使用Yolov5里面的 export.py实现模型的转换。 一&#xff1a;安装依赖 因为yolov5里面的requirments.txt是将这些转换模型的都注释掉了 所以需要解除注释…

SAP如何批量标记生产订单的TECO状态

声明&#xff1a;本文仅代表作者观点和立场&#xff0c;不代表任何公司&#xff01;仅用于SAP软件应用学习参考。 SAP/ERP系统生产订单完工后&#xff0c;在进行结算之前&#xff0c;需要进行技术性完成操作&#xff0c;即将生产订单批量标记TECO&#xff0c;标记上TECO表示生…

独立站运营教程:站外引流如何做?

在当今全球化的商业环境中&#xff0c;跨境电商已经成为一个蓬勃发展的行业。对于跨境电商独立站来说&#xff0c;站外引流是非常关键的一环&#xff0c;它可以帮助独立站吸引更多潜在客户&#xff0c;提升品牌知名度&#xff0c;促进销售增长。本文将深入探讨如何实现跨境电商…

eNSP学习——静态路由及默认路由基本配置

目录 知识背景 实验目的 实验步骤 实验内容 实验拓扑 实验编址 实验前期准备 实验步骤 1、基本配置&#xff08;按照实验编址设置好对应的IP地址&#xff09; 2、是实现主机之间的通信 3、实现全网全通来增强网络的可靠性 4、使用默认路由实现简单的网络优化 需要各…

【静态分析】静态分析笔记07 - 指针分析基础

参考&#xff1a; 【课程笔记】南大软件分析课程7——指针分析基础&#xff08;课时9/10&#xff09; - 简书 -------------------------------------------------------------- 1. 指针分析规则 规则&#xff1a;采用推导形式&#xff0c;横线上面是条件&#xff0c;横线下…

MySQL--表的操作

目录 创建表 查看表结构 修改表 新增列 修改列类型 修改列名 修改表名&#xff1a; 删除列 删除表 创建表 语法&#xff1a; CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引…

【论文阅读】Self-DC:何时检索,何时生成?

对于RAG来说&#xff0c;什么时候利用外部检索&#xff0c;什么时候使用大模型产生已知的知识&#xff0c;以回答当前的问题?这是一个非常有趣的话题。 《Self-DC: When to retrieve and When to generate? Self Divide-and-Conquer for Compositional Unknown Questions》这…

【设计模式】12、observer 观察者模式

文章目录 十二、observer 观察者模式12.1 subscriber12.1.1 broker_test.go12.2.2 broker.go12.2.3 client.go 十二、observer 观察者模式 https://refactoringguru.cn/design-patterns/observer 发布订阅模式, client 都可以向 broker 注册, broker 管理所有 connection, 当…

MySQL尾部空格处理与哪些设置有关? 字符集PAD SPACE与NO PAD属性的区别、MySQL字段尾部有空格为什么也能查询出来?

文章目录 一、问题背景二、字符集PAD_ATTRIBUTE属性&#xff08;补齐属性&#xff09;2.2、PAD SPACE与NO PAD的具体意义 三、CHAR类型尾部空格的处理四、其他问题4.1、在PAD SPACE属性时如何实现精准查询 五、总结 以下内容基于MySQL8.0进行讲解 一、问题背景 一次查询中发现…

Threejs加载字体加载FontLoader与TTFLoader

在 Three.js 中使用自定义字体进行 3D 文本渲染。它最初是以 JSON 格式加载字体&#xff0c;现在Three.js已经有一个 TTFLoader 类&#xff0c;可用于加载 TTF 字体文件并将它们用作 TextGeometry &#xff01; 1、最初使用FontLoader加载json字体方法如下 const loader new…

NVIDIA CUDA Toolkit

NVIDIA CUDA Toolkit CUDA Toolkit 12.4 Update 1 Downloads | NVIDIA Developer CUDA Toolkit是用于CUDA开发的软件包&#xff0c;主要包括CUDA编译器、运行时库、GPU驱动程序和开发工具等。它允许开发者使用通用编程语言&#xff08;如C、C&#xff09;来利用NVIDIA GPU进行…

ZDOCK linux 下载(无需安装)、配置、使用

ZDOCK 下载 使用 1. 下载1&#xff09;教育邮箱提交申请&#xff0c;会收到下载密码2&#xff09;选择相应的版本3&#xff09;解压 2. 使用方法Step 1&#xff1a;将pdb文件处理为ZDOCK可接受格式Step 2&#xff1a;DockingStep 3&#xff1a;创建所有预测结构 1. 下载 1&…

2023平航杯——介质取证部分复现

闻早起的电脑 教徒“闻早起”所使用的笔记本电脑使用何种加密程式&#xff1f; VeraCrypt 教徒“闻早起”所使用的笔记本电脑中安装了一款还原软件&#xff0c;其版本号为&#xff1f;【标准格式&#xff1a;1.2.3.4】 8.71.020.5734 教徒“闻早起”所使用的笔记本电脑中登…

.gitignore语法及配置问题

语法及配置 前言.gitignore语法Git 忽略规则优先级gitignore规则不生效Java项目中常用的.gitignore文件c项目中常用的.gitignore注意事项 前言 在工程中&#xff0c;并不是所有文件都需要保存到版本库中&#xff0c;例如“target”目录及目录下的文件就可以忽略。在Git工作区的…

CSS中的 5 类常见伪元素详解!

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合…

使用python setup.py报错:Upload failed (403) / Upload failed (400)

当前报错的环境 Python 3.9.19twine1.15.0 本地~/.pypirc已正确配置了用户名和密码&#xff0c;用在pypi.org注册&#xff1a; [pypi]username skylerhupassword ${password}执行 python setup.py sdist upload -r pypi 打包上传到仓库报错。 在不久之前同样的环境&#…

2018-2023年上市公司富时罗素ESG评分数据

2018-2023年上市公司富时罗素ESG评分数据 1、时间&#xff1a;2018-2023年 2、来源&#xff1a;整理自WIND 3、指标&#xff1a;证券代码、简称、ESG评分 4、范围&#xff1a;上市公司 5、指标解释&#xff1a; 富时罗素将公司绿色收入的界定和计算作为公司ESG 评级打分结…

macbook m1 nacos集群启动失败报错的解决办法

问题来源&#xff1a;(黑马springcloud学习过程)P29-06-Nacos配置管理-nacos集群搭建 问题描述&#xff1a;详情见nacos.log和start.out WebServerException: Unable to start embedded Tomcat (mach-o file, but is an incompatible architecture (have ‘x86_64’, need ‘a…

记录如何用php将敏感文字内容替换为星号的方法

在PHP中&#xff0c;将敏感文字用星号替换通常涉及到字符串的搜索和替换操作。你可以使用PHP的内置函数str_replace()来实现这个功能。下面是一个基本的示例&#xff0c;展示如何将特定的敏感词替换为星号&#xff1a; <?php // 要检查的原始文本 $text "这个文本包…