STL map&set用法详解

文章目录

  • 1. 关联式容器
  • 2. 键值对 (KV模型)
  • 3. 树形结构的关联式容器
    • 3.1 set
    • 3.2 map
    • 3.3 multiset 和 multimap
  • 4. 例题练习

1. 关联式容器

  • 像我们所了解的STL中的部分容器,比如:vector、list、dequeue、forward_list(c++11)等这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那么什么又是关联式容器呢??两者之间又有什么区别呢??
  • 关联式容器也是用来存储数据的, 和序列性容器不一样的是,关联式容器是非线性的树结构,更准确的说是二叉树结构。各元素之间没有严格的物理上的顺序关系,也就是说元素在容器中并没有保存元素置入容器时的逻辑顺序。但是关联式容器提供了另一种根据元素特点排序的功能,这样迭代器就能根据元素的特点“顺序地”获取元素。关联式容器另一个显著的特点是它是以键值的方式来保存数据,就是说它能把关键字和值关联起来保存,而顺序性容器只能保存一种(可以认为它只保存关键字,也可以认为它只保存值)。其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高

2. 键值对 (KV模型)

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

  • 例:生活中的KV模型,比如英汉字典,在字典中每个单词都有其对一个的含义,我们可以通过单词找到相应的意思。

  • SGI-STL中关于键值对的定义

template <class T1, class T2>
struct pair
{
	typedef T1 first_type;
	typedef T2 second_type;
	T1 first;
	T2 second;
	pair(): first(T1()), second(T2())
	{}
	pair(const T1& a, const T2& b): first(a), second(b)
	{}
};

3. 树形结构的关联式容器

在本文中我们介绍,set、multiset、map、multimap、。这四种容器的共同点是:使用平衡搜索树(即红黑树)最为其底层结构 ,容器中的元素是一个有序的序列。

3.1 set

  • set相关内容可以去cplusplus中查询->link

介绍set:

  • set是按照一定次序存储元素的容器,在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。set在底层是用二叉搜索树(红黑树)实现的。

  • 作用:排序+去重 STL map&set用法详解_第1张图片

  • 那么很多人就会问,我们要是想拿set排降序怎么办呢??
    STL map&set用法详解_第2张图片

  • set迭代器的使用
    STL map&set用法详解_第3张图片
    总结:
    1 . set中插入元素时,只需要插入value即可,不需要构造键值对。
    2 . set中的元素不可以重复(因此可以使用set进行去重)。
    3 . 使用set的迭代器遍历set中的元素,可以得到有序序列。
    4 . set中的元素默认按照小于来比较。
    5 . set中查找某个元素,时间复杂度为:O(log2N)…

3.2 map

STL map&set用法详解_第4张图片

  • map相关内容可以去cplusplus中查询->link

介绍map:

  • map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
    在map中,键值key通常用于排序和惟一地标识元素而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:typedef pair value_type;在内部,map中的元素总是按照键值key进行比较排序的。map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

  • 使用map:
    map的模板参数说明:
    STL map&set用法详解_第5张图片
    STL map&set用法详解_第6张图片

  • 在使用里面我们要着重掌握 []
    STL map&set用法详解_第7张图片

  • 了解了 [] 的作用之后,我们就可以使用 [] 来统计次数:
    STL map&set用法详解_第8张图片

map总结:

  1. map中的的元素是键值对。
  2. map中的key是唯一的,并且不能修改。
  3. 默认按照小于的方式对key进行比较。
  4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列。
  5. map的底层为平衡搜索树(红黑树),查找效率比较高O(log2N)。
  6. 支持[]操作符,operator[]中实际进行插入查找。

3.3 multiset 和 multimap

  • multiset相关内容可以去cplusplus中查询->link
  • multimap相关内容可以去cplusplus中查询->link

介绍:

  • multiset/multiimap 和set/map 只有一个大区别就是:multiset与multimap 里面的值可以重复
    除了这点,其他可对比于set和map去使用。
    STL map&set用法详解_第9张图片

4. 例题练习

  • LeetCode-692-前K个高频单词->link
    STL map&set用法详解_第10张图片
  • 代码示例
class Solution {
public:
    struct com
    {
        bool operator()(const pair<string,int> &a,const pair<string,int> &b)
        {
            if(a.second != b.second)
            {
                return a.second > b.second;
            }
            else
                return a.first < b.first;
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        map <string,int> m;
        for(auto s:words)
        {
            m[s]++;
        }

        priority_queue<pair<string,int>, vector<pair<string,int>>, com> q;

        for(auto s:m)
        {
            q.push(s);
            if(q.size() > k)
            {
                q.pop();
            }
        }

        vector<string> ret;
        while(!q.empty())
        {
            ret.push_back(q.top().first);
            q.pop();
        }

        reverse(ret.begin(),ret.end());
        return ret;
    }
};

你可能感兴趣的:(C/C++,笔记,map,set,c++)