您现在的位置是:首页 >其他 >从STL的视角,了解下Map、Set、Tuple和Initializer_List的区别网站首页其他
从STL的视角,了解下Map、Set、Tuple和Initializer_List的区别
📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的
📖作者主页:热爱编程的小K
📖专栏链接:c++🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾
文章目录
一、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 << " " << 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 << " " << 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();
}