map/set(pair) 这些你懂吗???

来源:互联网 发布:娇韵诗白吸盘原理知乎 编辑:程序博客网 时间:2024/06/16 23:50

map/set

 map/set?????    到底说的是什么呢 ???、
很多人在刷题的时候可能会见过这两个名词、???   ,,,,但是你大概不知道这是什么意思????

那么,,我就来向你解释一下这两个名词到底是什么意思了!!!!!!!!


其实,说到底,,,,这两个就是系统为我们实现的两种二叉树《《《《;;;;;

但是这两种有一个共同之处,,,,那就是这两种结构的底层实现都是   使用的红黑树 ,,,,,通俗点说的话就是,这两种结构就是两种不同形态的红黑树。。。。。

那么,,,,,现在我们先了解一下这个set使用方法》》》》》

set

set的第一条规则就是这是一个 K 结构的红黑树。。。。。

下面我们我们通过一段代码来初步了解一下set的功能。。。。。
#pragma  once#include <iostream>using namespace std;#include<set>    //如果要是使用 set的结构 ,,,就要添加此头文件void  Testset(){set<int> testset;int arr[] =  {1,45,6,87,45,56,55,0,7,5};for(size_t i = 0 ;i < sizeof(arr)/sizeof(arr[0]);++i){testset.insert(arr[i]);}//其实set就是这个一个容器 ,,,,在这里使用迭代器输出这个set;;;;set<int>::iterator it= testset.begin();while(it!= testset.end()){cout<<*it<<" ";++it;}cout<<endl;};

最后生成的结果是 :::


通过这个结果显示,,我们可以明确的看出    ,生成的set的结构 中没有将数组中 重复的数字   输出。。。。
因此 ,我们可以看出set结构插入的时候 ,,,不会插入相同的元素 (红黑树都有这个特性
另外 ,输出的结果都是有序的,,,,,



因此,,,,我们可以得出set的几个功能:::

1、、、消除冗余的效果 ;;;;
2、、、对于一组不重复的数,达成排序的效果 。。。。

下面我们来看看库中,,,为我们实现的set的结构的一些操作函数。。。



在此图中我们可以看出 ,,,,set类的一系列组成;;;
其中 ,,,,
T   表示   的就是 set树中 的存储元素。。。。
Compare  表示   的就是   输出的元素顺序,,,(是升序还是降序,,,,,,在这里的缺省值是升序)
Alloc   表示   的就是    空间适配器。。。。。。。     (现在还不是很懂 )


下面是些  set的一些基本函数的用法;;;;;

这些就是 set 实现的函数   ;;;;
我在这里来 主要讲一下  insert函数   ::::


库函数 为  我们提供的insert函数  ,,,重载了三种方式  ;;;

下面我就向大家  来分别来  演示 一下  这三类重载函数的应用场景:::

场景1 、、、、函数原型 是
pair<iterator,bool> insert (const value_type& val);
此处的  value_type  表示类型就是 我们经常说的  K  类型  ,,,也就是set定义的T类型
此函数的返回值   类型为    pair<iterator,bool>
可能  你之前没有 听过pair这个 东西 ,点此来由我向你解释一下吧pair
 
void  Testset(){set<int> testset;int arr[] =  {1,45,6,87,45,56,55,0,7,5};for(size_t i = 0 ;i < sizeof(arr)/sizeof(arr[0]);++i){testset.insert(arr[i]);}pair<set<int>::iterator,bool>  ret =  testset.insert(100);cout<< * ret.first<<","<<ret.second<<endl;ret =  testset.insert(100);cout<< * ret.first<<","<<ret.second<<endl;}
显示的结果:


通过此我们可以看出 :::
如果 要是插入的元素已存在,,那么返回的pair类型 中的迭代器first为原有元素的迭代器,bool量second为false
如果 要是插入的元素不存在,,那么返回的pair类型 中的迭代器first为插入元素的迭代器,bool量second为true

此种用法我们可以用来解决下列问题:::
1、判断插入的数据 是否重复;;;
2、用来删除一组数据中重复的元素;;;;
3、排序一组无重复的数;;;;


场景2、、、、、函数原型 
iterator insert (iterator position, const value_type& val);
这就是我们 ,,,一般熟悉的一种场景 ,,,,在一个迭代器的之前插入这个数据,,,,返回插入元素的迭代器。。。。


场景3、、、函数
template <class InputIterator>void insert (InputIterator first, InputIterator last);
这是一个模板函数,,,,,,可以将一段数据插入到这个set红黑树中 ,,,,
使用实例:::
void  Testset(){set<int> testset;int arr[] =  {1,45,6,87,45,56,55,0,7,5};for(size_t i = 0 ;i < sizeof(arr)/sizeof(arr[0]);++i){testset.insert(arr[i]);}int   a[] = {100,200,300,400};testset.insert(a,a+4);set<int>::iterator it= testset.begin();while(it!= testset.end()){cout<<*it<<" ";++it;}cout<<endl;}
插入后输出的结果::
    
使用此类函数时,,,,需要注意的是:::
插入的迭代器必须可以 运用(++)(!=)这两个运算符;;;



set给我们
提供的删除函数 erase(),,也向我们提供了几种方法


重载的这些方法 ,,,我们 也很容易理解 ,,,,
(1)  参数是一个迭代器   
这就是 要删除  迭代器参数位置上的那个数据;;;
如果给的迭代器无效 ,,,,编译器就会报错 ,,,
(2) 参数是 一个数据,,,
也就是 要一个在set中值为val的节点 ;;;返回值为删除节点的个数

(3)  参数为一段迭代器区间

也就是 是 说 要删除 set的一段数据 ,,,,但是 所给的迭代器必须有效;;;

下面是这些方法使用实例:::
void Print(set<int> &s){set<int>::iterator it= s.begin();while(it!= s.end()){cout<<*it<<" ";++it;}cout<<endl;}void  Testset(){set<int> testset;int arr[] =  {1,45,6,87,45,56,55,0,7,5};for(size_t i = 0 ;i < sizeof(arr)/sizeof(arr[0]);++i){testset.insert(arr[i]);}Print(testset);set<int>::iterator it =  testset.find(5);testset.erase(it);//场景1的使用Print(testset);size_t  n =  testset.erase(45);//场景2的使用 Print(testset);testset.erase(testset.begin(),testset.end());//场景3的使用Print(testset);}
生成的结果:


如果要是场景一的删除的迭代器无效,,,,系统会提示这样的一个断言错误:::


另外,,,,,要是想要显示输出的数据元素 ,,,按照降序排列的话 ,,
可以 这样建立一个set的对象 :::
set<int,greater<int>>  s;

 map

关于map这种结构,,我呢,,,就不要详细说了  ,,,,它的使用几乎与  set是一致的。。。。

但大概还有一些区别 ,,,
下图为map的声明的原型 ,,,



上面的大部分和set是一模一样的;;;
只是这里的map是 K—V结构的一种 红黑树吧!!!

另外,,,,map的插入函数,,也和 set有区别:::
如果使用的     是    像 set一样的插入的话 ,,,,
代码该是这样的:
map<int ,int>  m;m.insert(1,2);
但是,,如果这样写的话,,,编译器会提示报错 ,,,,
为什么呢 ???
我们看看系统为我们提供的这种 插入函数就知道是怎么回事了 ???


大概一看,,和 set是一样的,,,但是 这里的value_type  指的是 一个pair 结构
key_typeThe first template parameter (Keymapped_typeThe second template parameter (Tvalue_typepair<const key_type,mapped_type>所以我们插入的时候 ,,,要这样的使用,,才能有效
map<int ,int>  m;m.insert(pair<int,int>(1,2));
为什么要这样写呢 ???
1】是为了 可观。。。。
2】是为与set对应。。。。

其他的一个十分重要的一点(与set相对比)是 :::
就是 map在这里  ,,,重载了 operator[]   ,,,,这是一个很关键的地方 。。。。
下面是函数的原型:::

在这里的作用有很多,,,,我们来这重载的代码来演示一下吧!!!!
T& operator[](const K& key){iterator it = find(key);//先在map里查找这个元素keyif(it == end())//没找到的话{it = insert(pair<k,T>(key,T())); //将这个数据插入到map中,,T为缺省值}return it->second;//返回值,,,,元素key的节点 V的引用}

也就是说,我们可以快速的通过 [key]  来找到它所对应的T值,,,,


这就是map、set的大概的知识 ;;;;

当然了,,我们学习它 ,,,,就是为了用它,,
如果,,你对此感兴趣的话,,可以来看看》》》》》
0 0
原创粉丝点击