介绍下set、map的区别,map.set方法
Yyds干货库存
在写之前,我们可以先看看现在map和set的相关知识。这里,我们先来看看它们的用法。最重要的是怎么模拟,不过这个应该是下一个博客,那个是红黑树。比这还难。地图和布景的底部是一棵红黑树,这一点我们以后会认识到。
在使用set之前,我们讲过数据模型,其中set就是K模型。在这里,我们不去探究底层,否则今天我们都会疯掉。我们先来看看标准库是如何描述set的。在这里,我先给大家解释一下,用set就是排序加权重。至于原因,我们以后再分析。
这里的模板参数大家应该都很熟悉了,这里就不解释了。我们先定义一个set类型的数据结构,方法在后面/
#包含集
使用命名空间std
int main()
{
设置int s;
返回0;
}
构造函数:首先我们来看一下press构造函数。set有三个构造函数。我们已经用过一个了,第二个是迭代器区间构造,第二个参数是仿函数对象,在我们插入数据排序的时候用到。
这里的迭代器,我们先看用法,底层不追究。很难意识到这一点。不过用法和以前一样。这里直接看一下吧。这是一个双向迭代器,即支持or-。这里只是一个普通的演示。
int main()
{
设置int s;
s .插入(1);
s .插入(3);
s . insert(2);
auto it=s . begin();
而(它!=s.end())
{
cout * it“”;
它;
}
返回0;
}
我来解释一下set的特点,这对我们很重要。我们插入的元素不能被修改。想想我们面前的搜索二叉树。如果允许我们修改值,还会构成搜索二叉树吗?反正我也不确定。
int main()
{
设置int s;
s .插入(1);
s .插入(3);
s . insert(2);
auto it=s . begin();
而(它!=s.end())
{
* it=10
cout * it“”;
它;
}
返回0;
}
也就是说,我们看起来有两个迭代器,实际上是由一个const修改的。
Insert()我们先来看看数据插入。一般不是线性表的数据结构。插入数据的方法一般是插入,设置也是如此。我们之前已经用过一个了,这里重点说一下第二个的使用。
这个函数的使用我们没有太大的问题,主要是返回值。这里第一个插页的放置好像是我们没见过的类型,这个主要用于后期的贴图。在这里,我们简单看一下。pair是由标准库定义的类型,标准库有两个模板参数,它在这里被实例化。
先简单用一下,分别看看这两个模板参数的作用。这里,我们来解释一下第一个。第一个是我们插入被插入元素对应的迭代器,后面会考虑下面的bool类型。下面这张图需要和大家详细分析一下。
int main()
{
设置int s;
auto it=s . insert(1);
s .插入(1);
返回0;
}
Erase()删除元素也很简单。注意这里的参数就可以了,不用过多考虑迭代器失败的问题。主要原因是我们通常使用第二个函数。
int main()
{
设置int s;
s .插入(1);
s . insert(2);
s . insert(2);
s .插入(3);
for(常量整数值:s)
{
cout val“”;
}
cout endl
s . erase(2);
For (const int val: s) //为什么在const引用实现的时候说?
{
cout val“”;
}
cout endl
返回0;
}
函数count()很有意思,就是记录了集合中某个元素的编号,集合中很少用到,但是下面的目录集合不错。我过会儿向你提及它。
int main()
{
设置int s;
s .插入(1);
s . insert(2);
s . insert(2);
s .插入(3);
cout s . count(1)endl;
返回0;
}multiset知道这也是集合类型的数据结构,但是支持重复插入相同的元素。有些方法和我们那套一样。就说数数吧。
int main()
{
multiset int s;
s .插入(1);
s .插入(2);
s .插入(2);
s .插入(3);
cout s . count(2)endl;
for(常量整数值:s)
{
cout val“”;
}
cout endl
返回0;
}
使用地图我们之前已经知道了KV模型,这里要说的地图就是一个典型代表。我们要讲的主要有两个,一个是insert,一个是operator重载,剩下的就不看了,用法都差不多。
Map也是我们常用的数据结构。一般来说,我们在插入的时候用key来比较,用V来存储数据。这里,V是可变的,但K是不可改变的。
在讨论pair之前,我们先来看看类型对,这是标准库中定义的类型,也是一个类模板。结构类似于下面的。我们不会在意它,直到我们使用它。
模板类别T1,类别T2
结构对
{
T1 fiest
T2第二;
};准确的说,是这样定义的。
Insert()这里是地图的插入。下面我们来看看它在我国的使用情况。
int main()
{
map int,int m;
m.insert(std:pair int,int (1,1));//两种用法,随便哪一种都行。
m.insert(make_pair(2,2));
返回0;
}
运算符[]是我们集合中没有的运算符,所以非常有用。首先我们要明白,在map中,我们不能修改K,但是V可以。这是我们想谈的。
int main()
{
映射字符串,字符串m;
米(meter的缩写))insert(成对字符串,字符串(桃子,桃子));
米(meter的缩写))insert(成对字符串,字符串( left , left ));
map string,string:iterator it=m . begin();
而(它!=m.end())
{
cout (*it)。first it-second endl;
它;
}
cout ======================== endl;
auto find=m . find( left );
如果(发现!=m.end())
{
find-second= remaining ;
}
it=m . begin();
而(它!=m.end())
{
cout (*it)。first it-second endl;
它;
}
返回0;
}
那么这里就有困惑了。我们可以修改v的值,但是这个运算符和它有什么关系呢?你不觉得这样写优点很麻烦吗?看看下面。
int main()
{
映射字符串,字符串m;
米(meter的缩写))insert(成对字符串,字符串(桃子,桃子));
米(meter的缩写))insert(成对字符串,字符串( left , left ));
map string,string:iterator it=m . begin();
而(它!=m.end())
{
cout (*it)。first it-second endl;
它;
}
cout ======================== endl;
M[左]=剩余;
it=m . begin();
而(它!=m.end())
{
cout (*it)。first it-second endl;
它;
}
返回0;
}
这里我们可以看一下这个运算符的原理,你看一下截图就明白了。我们后面会一步步分析。
我们知道insert将返回一对。这一对是我们的焦点,其中的第一个是我们插入元素的迭代器。我们可以通过迭代器找到对应的V值。即以下原则。
mapped_type运算符[](const key_type k)
{
对迭代器,bool ret=insert(make_pair(k,mapped _ type()));
ret . first-second返回;
}这里先来解释一下前面迭代器中的布尔类型,有点学过了。如果我们的元素成功插入,那么Bool值为true,否则为false。但是,当我们遇到不成功的插入时,其中通常存在相同的键值。
int main()
{
映射字符串,字符串m;
Auto t1=m. insert(成对字符串,字符串( left , left ));
Auto T2=m. insert(成对字符串,字符串( left , remaining ));
返回0;
}
那这里就有意思了。我们需要更好地理解这个重载操作符。
mapped_type运算符[](const key_type k)
{
对迭代器,bool ret=insert(make_pair(k,mapped _ type()));
ret . first-second返回;
}先说明数据类型,看看下面的截图就知道了。这里暂且把T当做V,等实现的时候再来分享。
也就是说,insert中的第二个参数就是我们面前的v,这里会自动生成一个匿名对象。对于int是0,其他类型会自动调用自己的默认构造函数。
这里再讨论两个案例。假设我们插入的键值不存在,那么这就是直接插入,返回的V可以直接在外面赋值。如果我们插入的键值存在,这里会有一个简单的搜索问题,返回值是V,我们可以修改。这就是重载该运算符的好处。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。