C++:set和map的使用

这篇具有很好参考价值的文章主要介绍了C++:set和map的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.关联式容器

序列式容器:比如我们之前讲的vector、string、list等均为序列式容器,特点是按元素顺序来保存和访问

关联式容器:比如本次讲的map和set,和序列式容器不同,其依靠键值来保存和访问,数据检索效率闭序列式容器高。
PS:本文只讲使用,set和map底层是一颗平衡二叉搜索树



2.key模型和key_value模型

(1)key模型:主要解决在不在的问题?比如现在录入人脸信息,用户登录的判断就可以采用key模型,set其实就是一个key模型。

#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;

int main() {
    set<string> s;
    vector<string> v = {"张三", "李四", "王五", "赵六"};
    for (auto e : v) s.insert(e);  //还没讲接口,这里的作用是录入信息
    string input;
    while (cin >> input)
    {
        if (s.count(input))  //这里的作用是在set中查找input是否存在
        {
            cout << "存在,查找成功" << endl;
        }
        else
        {
            cout << "不存在" << endl;
        }
    }
    return 0;
}

C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl

(2)key_value模型:和key模型最大的不同就是存储,key模型只存一个键值,而key_value模型存储的是一个键值对。除了可以解决在不在的问题,还可以通过键值找到对应信息,map其实就是一个key_value模型。

键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。

//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)
    {}
};

int main() {
    //还没讲接口,知道大概意思就行
    map<string, string> mapTranslation;  //就以英汉翻译词典为例子
    //录入词典的信息
    mapTranslation.insert(make_pair("left", "左边"));
    mapTranslation.insert(make_pair("right", "右边"));
    mapTranslation.insert(make_pair("sort", "排序"));
    mapTranslation.insert(make_pair("father", "父亲"));
    string input;
    while (cin >> input)
    {
        if (mapTranslation.count(input))  //这里也是查找在不在
        {
            cout <<  "中文为: " << mapTranslation[input] << endl;  //这里拿到value
        }
        else
        {
            cout << "词典无记录" << endl;
        }
    }
    return 0;
}

C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl


3.set

3.1一些注意点

  • set不允许键值冗余,比如插入3后不能再插入3。拒绝键值冗余,本就是二叉搜索树的定义。故set中不会有重复的元素,可以利用这一点对数据进行去重
  • set利用迭代器遍历元素,可以得到一个有序序列,可利用这一点对数据进行排序。原理是中序遍历二叉搜索树可以得到有序序列。
  • set元素默认按小于比较,即默认升序。
  • set不允许修改元素,如果支持修改会无法维护搜索二叉树的结构。
  • set中查找某个元素,时间复杂度为:logN

3.2set的使用

(1)模板参数
C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl

(2)构造

函数声明 功能
set (const Compare& comp = Compare(), const Allocator& = Allocator()) 空构造
set (InputIterator first, InputIterator last, 后面和空构造一样) 迭代器区间构造
set (const set& x) 拷贝构造

(3)迭代器

函数声明 功能
iterator begin() 返回set中起始位置元素的迭代器
iterator end() 返回set中最后一个元素后面的迭代器
reverse_iterator rbegin() 反向迭代器,返回end()
reverse_iterator rend() 反向迭代器,返回begin()的前一个位置

(4)容量

函数声明 功能
bool empty ( ) const 检测set是否为空,空返回true,否则返回false
size_type size() const 返回set中有效元素的个数

(5)增加、删除、查找

函数声明 功能
pair<iterator,bool> insert ( const value_type& x ) 在set中插入元素x,实际插入的是<x, x>构成的键值对,如果插入成功,返回<该元素在set中的位置,true>;如果插入失败,说明x在set中已经存在,返回<x在set中的位置,false>
void erase
( iterator position)
删除对应position位置的元素
size_type erase
( const key_type& x )
删除set中值为x的元素,返回删除的元素的个数
void erase
( iterator first, iterator last )
删除set中[first, last)区间中的元素
iterator find
( const key_type& x ) const
返回set中值为x的元素的迭代器,不存在返回end()
size_type count
( const key_type& x ) const
返回set中值为x的元素的个数
void swap (set& sp ) 交换两个set中的元素
void clear ( ) 将set中的元素清空

几个注意点:

  • insert的返回值希望大家记一下,方便大家理解map的核心接口。
  • 判断键值在不在set中有两种方法
    第一种是find(key),依据返回值判断,是end()代表不在,否则存在。
    第二种是count(key),如果存在返回非0,不存在返回0,也可以进行判断。
    选择习惯的方式即可。

3.3习题

链接:两个数组交集
题目要求:
C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl

代码加解析:

//主要思想是利用set进行去重
//(1)先用set1存储nums1的值,比如[1,2,2,1]->[1,2](set去重)
//(2)定义一个set2,如果nums2的值在set1中可以找到,就插入set2中
//注意:因为nums2中可能存在多个相同值,故用set可以进行去重
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        set<int> set_exist;
        set<int> result;
        for(auto e : nums1)
        {
            set_exist.insert(e);
        }
        for(auto e : nums2)
        {
            if(set_exist.find(e) != set_exist.end()) //如果存在
            {
                result.insert(e);
            }
        }
        return vector<int>(result.begin(), result.end());
    }
};

//这个题也可以先去重加排序
//交集:(1)不相等小的加加;(2)相等是交集,同时加加
//差集:(1)不相等小的是差集,小的加加;(2)相等都不是差集,同时加加 (3)一方走完,剩下的都是差集



4.multiset

multiset和set使用几乎一致,唯一的不同就是允许键值冗余。

  • 迭代器遍历依然可以得到有序序列
  • count()接口对multiset非常重要
  • multiset的find()查找返回的是中序遍历的第一个元素
  • multiset可以对存在重复元素的序列排序。



5.map

5.1一些注意点

  • 在内部,map中的元素总是按照键值key进行比较排序的,和value无关。
  • map不允许键值冗余,map中的键值对是唯一的。
  • 利用迭代器遍历可以得到有序序列,不过是按key来排序
  • map不允许修改key,但可以修改value。支持修改键值会无法维护二叉搜索树结构。
  • map中查找某个元素,时间复杂度为:logN

5.2map的使用

(1)模板参数
C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl

(2)构造

函数声明 功能
map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type()) 空构造
map (InputIterator first, InputIterator last, 后面和空构造一样) 迭代器区间构造
map (const map& x) 拷贝构造

(3)迭代器

函数声明 功能
iterator begin() 返回set中起始位置元素的迭代器
iterator end() 返回set中最后一个元素后面的迭代器
reverse_iterator rbegin() 反向迭代器,返回end()
reverse_iterator rend() 反向迭代器,返回begin()的前一个位置

(4)容量

函数声明 功能
bool empty ( ) const 检测set是否为空,空返回true,否则返回false
size_type size() const 返回set中有效元素的个数

(5)增加、删除、修改、查找

函数声明 功能
pair<iterator,bool> insert ( const value_type& x ) 在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表是否插入成功
void erase
( iterator position)
删除对应position位置的元素
size_type erase
( const key_type& x )
删除map中键值为x的元素,返回删除的元素的个数
void erase
( iterator first, iterator last )
删除map中[first, last)区间中的元素
iterator find
( const key_type& x ) const
返回map中键值为x的元素的迭代器,不存在返回end()
size_type count
( const key_type& x ) const
返回map中键值为x的元素的个数
mapped_type& operator[]
(const key_type& k)
非常重要
返回key对应的value
void swap ( map& mp ) 交换两个map中的元素
void clear ( ) 将map中的元素清空

几个注意点:

  1. 这里的接口中最重要的就是operator[],因为[]不仅可以访问value,还可以进行插入
    operator[]的原理是: 用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中如果key已经存在,插入失败,如果不存在就进行插入。insert返回的键值对第一个元素就是元素对应的迭代器,operator[]函数通过迭代器最后返回键值对中的value的引用。
  2. 对map的迭代器解引用得到是键值对结构体,设迭代器为x,拿value的方式有两种。(*x).secondx->second
  3. map判断键值对在不在的方式和前面set一致

5.3习题

链接:前k个高频单词
题目要求:
C++:set和map的使用,C++进阶,c++,开发语言,笔记,学习方法,stl
代码加解析:

//这里的核心思路:
//(1)用map统计每个字符串出现次数
//(2)对键值对进行排序,出现次数相同的要按字典序来排
//     因为键值对自带的比较规则是只按key排序的,所以我们需要自定义排序(比较方法)
//其实只是访问的话unordered_map更加快速,但unordered_map迭代器遍历无法保证有序
class compare
{
public:
    bool operator()(pair<string,int> p1, pair<string,int> p2) const
    {
        if(p1.second == p2.second)
        {
            //出现次数相同,按字典序排
            return p1.first < p2.first;
        }
        else
        {
            //要排降序,按大于排
            return p1.second > p2.second;
        }
    }
};
class Solution {
public:
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string, int> count_map;  //用map统计
        for(int i = 0; i < words.size(); i++){
            count_map[words[i]] ++;
        }
        //排序(降序)
        vector<pair<string,int>> result(count_map.begin(), count_map.end());;
        sort(result.begin(),result.end(),compare());
        vector<string> ret;
        for(int i = 0; i < k; i++)
            ret.push_back(result[i].first);
        return ret;
    }
};
//也可以利用set进行排序
// set<pair<string, int>, compare> sort_set(count_map.begin(), count_map.end());
// vector<string> ret;
// auto it = sort_set.begin();
// while(k--)
// {
//     ret.push_back(it->first);
//     it++;
// }
// return ret;



6.multimap

multimap和map使用几乎一致,最大的不同就是允许键值冗余文章来源地址https://www.toymoban.com/news/detail-744339.html

  • multimap没有支持operator[]
    原因是存在多个同键值的键值对,不知道取谁的value。
  • 迭代器遍历依然可以得到有序序列。
  • count()接口对multimap非常重要。
  • multimap的find()查找返回的是中序遍历的第一个元素
  • multimap可以对存在重复元素的序列排序。

到了这里,关于C++:set和map的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++进阶:详细讲解容器set与map(pair、multiset、multimap)

    C++进阶:详细讲解容器set与map(pair、multiset、multimap) 上次介绍了搜索二叉树:C++进阶:二叉搜索树介绍、模拟实现(递归迭代两版本)及其应用 为了介绍后面的AVLTree和红黑树,我们要进行一些铺垫,就是set与map的介绍啦 关联式容器和序列式容器是 C++ 中两种不同的容器类

    2024年04月12日
    浏览(40)
  • C++:set和map的使用

    序列式容器:比如我们之前讲的vector、string、list等均为序列式容器,特点是 按元素顺序来保存和访问 。 关联式容器:比如本次讲的map和set,和序列式容器不同,其 依靠键值来保存和访问 ,数据检索效率闭序列式容器高。 PS:本文只讲使用,set和map底层是一颗 平衡二叉搜索

    2024年02月05日
    浏览(49)
  • 【C++】set和map的使用

    对于STL容器来说,有很多相似的功能,所以这里主要将与之前不同的功能说清楚 vector/list/deque 作为序列式容器(类似于线性表的存储方式) map与set作为关联式容器,里面存储的是key,value结构的键值对(数据之间有非常强的关联关系) 键值对:用来表示一 一对应的关系,key代表键

    2024年02月04日
    浏览(34)
  • 【C++学习】map和set的使用

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! map和set的底层都是二叉搜索树,只是做了更进一步的限制,使其不会出现单只的情况,搜索的时间复杂度保证在O(log 2 N),具体的底层结构后面本喵再详细介绍,现在先来认识以下set和

    2023年04月19日
    浏览(35)
  • C++【set 和 map 学习及使用】

    ✨个人主页: 北 海 🎉所属专栏: C++修行之路 🎃操作环境: Visual Studio 2019 版本 16.11.17 set 和 map 是 STL 中的容器之一,不同于普通容器,它俩的查找速度极快,常用来存储各种经常被检索的数据,因为这俩容器的底层是平衡二叉搜索树中的红黑树。除此之外,还可以借助其

    2024年02月09日
    浏览(74)
  • C++:map和set的介绍及使用

    目录 1. 关联式容器 2. 键值对 3. 树形结构的关联式容器 3.1 set 3.1.1 set的介绍 3.1.2 set的使用 3.2 map 3.2.1 map的介绍 3.2.2 map的使用 3.3 multiset 3.3.1 multiset的介绍 3.3.2 multiset的使用 3.4 multimap 3.4.1 multimap的介绍 3.4.2 multimap的使用 在之前文章中,我们已经接触过STL中的部分容器,比如:

    2024年02月03日
    浏览(36)
  • 【C++】详解map和set基本接口及使用

    关联式容器也是用来存储数据的,但与序列式容器不同的是,关联式容器里面存储的是 key, value 结构的键值对,因此**在数据检索时比序列式容器效率更高**。 键值对是用来表示 具有一一对应关系的一种结构 ,该结构中一般只包含两个成员变量 – key 和 value;其中 key 代表键

    2024年02月08日
    浏览(44)
  • 【C++】使用红黑树进行封装map和set

    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘 。 🛸 C++专栏 : C++内功修炼基地 家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我真

    2024年02月07日
    浏览(47)
  • 【C++】map、set、multimap、multiset的介绍和使用

    我讨厌世俗,也耐得住孤独。 1. 之前所学的vector,list,deque等容器都是序列式容器,因为他们的底层数据结构都是线性的,并且数据结构中存储的都是元素数据本身,也就是单一的变量。 而下面所学的set、map、multimap、multiset等容器都是关联式容器,他们内部存储的不再是单

    2023年04月15日
    浏览(41)
  • 【C++】STL——set/multiset 和 map/multimap的使用

    在初阶阶段,我们已经接触过STL中的部分容器 比如:vector、list、deque、forward_list(C++11)等,这些容器统称为 序列式容器 ,因为其底层为线性序列的数据结构,里面存储的是元素本身。 而今天我们要学习的几个容器称为关联式容器,那什么是关联式容器?它与序列式容器有什

    2024年02月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包