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

简介: 📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的📖作者主页:热爱编程的小K📖专栏链接:c++🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾————————————————版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_72157449

文章目录


一、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、操作基本数据类型

微信截图_20230425215136.png


void testOne()

{

map data;

//下标法插入

data[0] = string("king");

data[-1] = string("空");

//insert函数插入

data.insert(pair(5, "貂蝉"));

data.insert(make_pair(3, "妲己"));

data.insert(pair(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& 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> test;

test.insert(pair(1, "king"));

test.insert(make_pair(2, "吕布"));

test.insert(pair(1, "貂蝉"));

test.insert(make_pair(1, "狂铁"));

test.insert(pair(1, "king"));

for (auto v : test)

{

 cout << v.first << "\t" << v.second << endl;

}

}


4、操作自定义类型

微信截图_20230425215328.png


——————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 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、操作基本类型


微信截图_20230425215136.png微信截图_20230425215136.png

微信截图_20230425215506.png微信截图_20230425215525.png微信截图_20230425215547.png微信截图_20230425215559.png

4、操作自定义类型

注意自己写排序准则

微信截图_20230425215726.png

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 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的作用是允许您使用列表初始化语法来初始化各种类型的对象,包括数组、向量和用户定义的类型。


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; } }实现了列表初始化的方式


微信截图_20230425215856.png#include

#include

using namespace std;

template 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 test1 = { 1,2,5,8,9,10 };

test1.printData();

myVector test2 = { 2,5,8,9,0 };

test2.printData();

return 0;

}

四、tuple

1、概念与定义

tuple是C++标准库的一个特性,它允许您将多个值作为一个整体进行处理。它在C++11中引入,并在头文件中定义。

tuple是一个包含不同类型元素的序列的对象。它类似于结构体,但是它是只读的并且没有成员名称。您可以使用它来返回多个值,或者将多个值作为参数传递给函数。tuple就是元组的意思,它是一个可变参模板类,也就是传入的参数随便写,并且数目不定


2、tuple的使用

可以通过get方法获取,获取下标必须是常量,类型转换也不行,所以使用比较舒服,但是调用比较困难

可以通过宏定义,简便获取

可以通过tie函数获取

tuple_cat可以实现两个元组之间的拼接

微信截图_20230425220012.png

#include

#include

#include

using namespace std;

void testOne()

{

tuple data = { "king",1,2,2.33 };

tuple 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(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();

}


原文链接:https://blog.csdn.net/qq_72157449/article/details/130282430


相关文章
|
6月前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。
|
6月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
402 2
|
6月前
|
存储 Java 索引
(Python基础)新时代语言!一起学习Python吧!(二):字符编码由来;Python字符串、字符串格式化;list集合和tuple元组区别
字符编码 我们要清楚,计算机最开始的表达都是由二进制而来 我们要想通过二进制来表示我们熟知的字符看看以下的变化 例如: 1 的二进制编码为 0000 0001 我们通过A这个字符,让其在计算机内部存储(现如今,A 字符在地址通常表示为65) 现在拿A举例: 在计算机内部 A字符,它本身表示为 65这个数,在计算机底层会转为二进制码 也意味着A字符在底层表示为 1000001 通过这样的字符表示进行转换,逐步发展为拥有127个字符的编码存储到计算机中,这个编码表也被称为ASCII编码。 但随时代变迁,ASCII编码逐渐暴露短板,全球有上百种语言,光是ASCII编码并不能够满足需求
278 4
|
9月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
626 1
|
10月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
686 156
|
10月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
567 0
|
10月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
148 0
|
10月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
358 0
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
345 2

热门文章

最新文章

下一篇
开通oss服务