从STL的视角,了解下Map、Set、Tuple和Initializer_List的区别

article/2025/3/1 6:40:35

在这里插入图片描述

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的
📖作者主页:热爱编程的小K
📖专栏链接:c++

🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾

在这里插入图片描述

文章目录

    • 一、map/multimap
      • 1、map/multimap的简介
      • 2、核心注意
      • 3、操作基本数据类型
      • 4、操作自定义类型
    • 二、set/multiset
      • 1、set/multiset简介
      • 2、核心注意
      • 3、操作基本类型
      • 4、操作自定义类型
    • 三、initializer_list
      • 1、概念与定义
      • 2、写一个自己的Vector
    • 四、tuple
      • 1、概念与定义
      • 2、tuple的使用


一、map/multimap

1、map/multimap的简介

map(映射)是关联容器,用于存储按特定顺序由键值映射值的组合形成的元素,即(key,value)对。它提供基于key的快速检索能力。

map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。

map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。

map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。

multimap与map的区别:set支持唯一键值,每个key只能出现一次;而multiset中同一key可以出现多次。map支持[]操作符,但是multmap不支持

2、核心注意

map是映射,映射就是数学的对应关系 ,例如 y=x

  • map中存储的是数对类型: pair<_Ty1,Ty2>
    • first : 键
    • second:值
  • map具有排序性,按照键排序 ,按照first进行的排序
  • map键唯一性

multimap映射,键不唯一

  • 不存在下标法插入
  • 具有排序

3、操作基本数据类型

在这里插入图片描述

void testOne() 
{	map<int, string> data;//下标法插入data[0] = string("king");data[-1] = string("空");//insert函数插入data.insert(pair<int, string>(5, "貂蝉"));data.insert(make_pair<int, string>(3, "妲己"));data.insert(pair<int, string>(3, "狂铁")); //键值相同,insert函数不做插入data[3] = string("孙悟空");       //下标法,保留最新值for (auto v : data) {cout << v.first<< " " << v.second<< endl;}cout << endl;//删除auto iter = find_if(data.begin(), data.end(), [](const pair<int, string>& object) {return object.first == 0; });data.erase(iter);for (auto i = data.begin(); i != data.end(); i++) {cout << i->first << " " << i->second << endl;}
}
void testThree() 
{multimap<int, string, greater<int>> test;test.insert(pair<int, string>(1, "king"));test.insert(make_pair<int, string>(2, "吕布"));test.insert(pair<int, string>(1, "貂蝉"));test.insert(make_pair<int, string>(1, "狂铁"));test.insert(pair<int, string>(1, "king"));for (auto v : test) {cout << v.first << "\t" << v.second << endl;}
}

4、操作自定义类型

在这里插入图片描述

class MM 
{
public:MM(string name="", int age=0):name(name),age(age){}friend ostream& operator<<(ostream& out,const MM& object){out << object.name << "\t" << object.age << " " << "配对:" << " ";return out;}int getAge()const { return age; }
protected:string name;int age;
};
struct cmpByage 
{bool operator()(const MM& one, const MM& two) const{return one.getAge() < two.getAge();}
};
class GG 
{
public:GG(string name = "", int age = 0) :name(name), age(age) {}friend ostream& operator<<(ostream& out, const GG& object) {out << object.name << " " << object.age << endl;return out;}
protected:string name;int age;
};
void testTwo() 
{map<MM, GG, cmpByage> king;king[MM("貂蝉", 19)] = GG("狂铁", 20);king[MM("妲己", 28)] = GG("吕布", 29);king[MM("月亮", 15)] = GG("太阳", 33);for (auto v : king) {cout << v.first;cout << v.second;}}

二、set/multiset

1、set/multiset简介

set是一个***集合***容器,其中所包含的元素是***唯一***的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。

set采用***红黑树***变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。

multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次
不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。

2、核心注意

set叫做集合,这个容器具有两个特性

  • 自带排序
  • 去重

多重集合 multiset

  • 只具有排序性

3、操作基本类型

在这里插入图片描述
在这里插入图片描述

void testOne() 
{set<int> test;set<int, less<int>> test1; //和默认的一样,都是从小到大test.insert(1);test.insert(1);test.insert(0);test.insert(9);test.insert(5);for (auto v : test) {cout << v << " ";}cout << endl;//删除操作auto iter = find_if(test.begin(), test.end(), [](int var) {return var == 1; });test.erase(iter);for (auto v : test) {cout << v << " ";}cout << endl;
}
void testthree()
{multiset<int, greater<int>> king;king.insert(1);king.insert(1);king.insert(1);king.insert(0);king.insert(999);for (auto v : king) {cout << v << " ";}}

4、操作自定义类型

注意自己写排序准则

在这里插入图片描述

class MM {
public:MM(string name=" ",int age=0):name(name),age(age){}friend ostream& operator<<(ostream& out, const MM& object) {out << object.name << " " << object.age << endl;return out;}int getAge()const { return age; }
protected:string name;int age;
};
class cmpByage {
public:bool operator()(const MM& one, const MM& two) const {return one.getAge() < two.getAge();}
};
void testTwo()
{set<MM, cmpByage> info;info.insert(MM("king", 19));info.insert(MM("妲己", 18));info.insert(MM("貂蝉", 22));for (auto v : info) {cout << v;}
}

三、initializer_list

1、概念与定义

initializer_list是列表数据,就是{a,b,c…}数据

initializer_list是C++标准库的一个特性,它允许您将一系列值传递给函数或构造函数。它在C++11中引入,并在<initializer_list>头文件中定义。initializer_list是一个包含相同类型元素序列的对象。它类似于数组,但是它是只读的并且具有固定的大小。您可以使用它来初始化各种类型的对象,包括数组、向量和用户定义的类型。因此,initializer_list的作用是允许您使用列表初始化语法来初始化各种类型的对象,包括数组、向量和用户定义的类型。

2、写一个自己的Vector

myVector(int size) :curSize(0) { pre = new _Ty[size]; }实现了vector后面更小括号的方式开大小的方法myVector(const initializer_list<_Ty>& data) :pre(new _Ty[data.size()])

{ for (auto v : data) { pre[curSize++] = v; } }实现了列表初始化的方式

在这里插入图片描述

#include<iostream>
#include<initializer_list>
using namespace std;
template<class _Ty> class myVector 
{
public:myVector(int size) :curSize(0) { pre = new _Ty[size]; }myVector(const initializer_list<_Ty>& data) :pre(new _Ty[data.size()]) {for (auto v : data) {pre[curSize++] = v;}}void printData() {for (int i = 0; i < curSize; i++) {cout << pre[i] << " ";}cout << endl;}
protected:_Ty* pre;int curSize;
};
int main() 
{myVector<int> test1 = { 1,2,5,8,9,10 };test1.printData();myVector<int> test2 = { 2,5,8,9,0 };test2.printData();return 0;
}

四、tuple

1、概念与定义

tuple是C++标准库的一个特性,它允许您将多个值作为一个整体进行处理。它在C++11中引入,并在头文件中定义。
tuple是一个包含不同类型元素的序列的对象。它类似于结构体,但是它是只读的并且没有成员名称。您可以使用它来返回多个值,或者将多个值作为参数传递给函数。tuple就是元组的意思,它是一个可变参模板类,也就是传入的参数随便写,并且数目不定

2、tuple的使用

  • 可以通过get方法获取,获取下标必须是常量,类型转换也不行,所以使用比较舒服,但是调用比较困难
  • 可以通过宏定义,简便获取
  • 可以通过tie函数获取
  • tuple_cat可以实现两个元组之间的拼接

在这里插入图片描述

#include<iostream>
#include<tuple>
#include<string>
using namespace std;
void testOne() 
{tuple<string, int, int, double> data = { "king",1,2,2.33 };tuple<string, int, float, double> data1 = { "貂蝉",1,2.99,9.33 };//get方法获取,获取下标必须是常量,类型转换也不行,所以使用比较舒服,但是调用比较困难cout << get<0>(data1) << " " << get<1>(data1) << " " << get<2>(data1) << " " << get<3>(data1) << " " << endl;
#define Data(index) get<index>(data1)cout << Data(0) << " " << Data(1) << " " << Data(2) << " " << Data(3) << endl;string a;int b;float c;double d;tie(a, b, c, d) = data1;cout << a << " " << b << " " << c << " " << d << endl;//忽略数据tie(a, ignore, ignore, ignore) = data1;cout << a << endl;//拼接数据auto info = tuple_cat(data, data1);cout << get<0>(info) << " " << get<1>(info) << " " << get<2>(info) << " "<< get<3>(info) << " " << get<4>(info) << " " << get<5>(info) << " "<< get<6>(info) << " " << get<7>(info) << endl;
}
int main() 
{testOne();
}

http://chatgpt.dhexx.cn/article/MVI3Y4eg.shtml

相关文章

用Java模拟行星的运动

这段时间都在寝室里自学Java,就想自己写个小程序玩一玩。同时&#xff0c;我也是个三体迷&#xff0c;就想着能不能用学的Java来模拟一下三体运动。这个程序算是我正式写模拟三体运动前的一个尝试。 一、程序分析 首先来百度一番查一下太阳、水星、金星和地球的各种参数(非精确…

java课程设计旋转的行星_Java编程实现的模拟行星运动示例

本文实例讲述了Java编程实现的模拟行星运动。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 期待了很久的Java语言程序设计也拉下了帷幕&#xff0c;在几个月的时间里基本掌握了java的简单用法&#xff0c;学习了java的主要基础知识&#xff0c;面向对象思想&#xff…

JS-圆,椭圆等轨迹相关算法

圆 公式 (x0, y0) 圆心坐标 r&#xff1a;半径 x x0 cos(angle) * r y y0 sin(angle) * r 1、轨迹 <div id"div" style"position:relative; width: 20px; height: 20px; background: cadetblue;"></div><script>/*** 圆心 (x0, y0…

精确绘制椭圆

本文首发于微信公众号「3D视觉工坊」。 前言 圆特征在测量领域中应用广泛&#xff0c;比如&#xff1a;相机标定、位姿估计、目标跟踪等方面。圆经过透视投影&#xff0c;当成像平面与圆平面不平行时&#xff0c;圆经过透视投影为椭圆&#xff0c;圆心的透视投影点与椭圆的中…

cesium椭圆编辑椭圆修改(cesium篇.78)

听老人家说:多看美女会长寿 地图之家总目录(订阅之前必须先查看该博客) 完整代码工程包下载 运行如有问题,可“私信”博主。效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en

JS小球绕着椭圆形的轨迹旋转并且近大远小

在ivx中案例如下&#xff1a; VxEditor 效果如下&#xff0c;近大远小 主要代码如下&#xff1a; const centerX 360 / 2; // 椭圆中心的X坐标 const centerY 120 / 2; // 椭圆中心的Y坐标 const a 100; // 长半轴 const b 60; // 短半轴const elementsWithClassName d…

知识图谱实战应用2-知识图谱的知识融合与知识消歧

大家好,我是微学AI,今天给大家带来知识图谱实战应用2-知识图谱的知识融合与知识消歧。 知识图谱是用于表示语义化信息的一种图形化知识表示形式,其中包含了大量的实体、属性和关系。由于知识图谱是由不同来源的知识组成的,因此可能存在同一实体在不同知识源中有不同的表达…

【知识图谱】深入浅出讲解知识图谱(技术、构建、应用)

本文收录于《深入浅出讲解自然语言处理》专栏&#xff0c;此专栏聚焦于自然语言处理领域的各大经典算法&#xff0c;将持续更新&#xff0c;欢迎大家订阅&#xff01;个人主页&#xff1a;有梦想的程序星空个人介绍&#xff1a;小编是人工智能领域硕士&#xff0c;全栈工程师&a…

知识图谱从入门到应用——知识图谱的知识表示:符号表示方法

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 在前面的文章中已经多次提到&#xff0c;知识图谱采用图的方…

《什么是知识图谱?为什么需要知识图谱?知识图谱有什么应用? - 翔哥带你初识知识图谱》

原创实在不易&#xff0c;欢迎大家关注我微信公众号&#xff1a;阳洋up 我本人主要是做知识图谱表示学习研究的&#xff0c;通过读取大量CCF顶会论文以及与导师的交流沟通&#xff0c;逐渐形成了对知识图谱的大的层面上的一些认知&#xff0c;希望在CSDN平台上分享我的一些学习…

知识图谱从入门到应用——知识图谱的知识表示:向量表示方法

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 前文已经介绍过&#xff0c;向量化的表示已经在人工智能的其…

知识图谱|知识图谱的典型应用

作者&#xff1a; cooldream2009 我们构建知识图谱的目的&#xff0c;在于利用知识图谱来做一些事情。有效利用知识图谱&#xff0c;就是要考虑知识图谱的具备的能力&#xff0c;知识图谱具有哪些能力呢&#xff0c;首先我们知道知识图谱包含了海量的数据&#xff0c;是一个超…

知识图谱入门知识(一)知识图谱应用以及常用方法概述

学习内容 搜集各种博客&#xff0c;理解实体识别、关系分类、关系抽取、实体链指、知识推理等&#xff0c;并且总结各种分类中最常用的方法、思路。 由于自己刚刚接触知识图谱&#xff0c;对该领域的概念和方法的描述还不是很清楚&#xff0c;所以只是简单的列出框架和添加链接…

时空知识图谱应用初探

一、时空知识图谱概述 时空知识图谱不单单是一个“增强型”的开放域知识图谱&#xff0c;而是需要结合业务场景和领域知识&#xff0c;并针对时空知识自身的特点&#xff0c;对知识的概念、实体和关系进行语义化和时空化拓展。时空知识图谱除了描述语义关系外&#xff0c;还需要…

【知识图谱】知识图谱应用

知识图谱怎么用 知识图谱应用场景 辅助搜索——精准回答 eg&#xff1a; 辅助问答——人机互动 eg&#xff1a; 辅助数据集成——智能数据整合 eg&#xff1a; 辅助决策——智能决策 知识图谱和各种AI技术综合使用能更好地发挥AI的作用 eg&#xff1a;wbq为什么选择张…

知识图谱从入门到应用——知识图谱的知识表示:基础知识

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 知识表示是人工智能领域一个较为核心的问题。对于知识表示的…

知识图谱从入门到应用——知识图谱的技术结构

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 知识图谱是交叉技术领域 知识图谱是典型的交叉技术领域。在人工智能和机器学习领域&#xff0c;传统符号知识表示是知识…

知识图谱从入门到应用——知识图谱的发展

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 1945年&#xff0c;美国首任总统科学顾问Vannevar Bush曾提出了一个称为MEMEX的“记忆机器”的设想。他认为人的记忆偏重…

知识图谱从入门到应用——知识图谱的基础知识

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 知识图谱是有学识的人工智能 早期的人工智能有很多持不同观点的流派&#xff0c;其中两个历史比较悠久的流派通常被称为…

知识图谱的应用领域

1.3 知识图谱的价值 知识图谱最早的应用是提升搜索引擎的能力。随后&#xff0c;知识图谱在辅助智能问答、自然语言理解、大数据分析、推荐计算、物联网设备互联、可解释性人工智能等多个方面展现出丰富的应用价值。 1.辅助搜索 互联网的终极形态是万物的互联&#xff0c;而…