• set和map使用讲解


    目录

    1.set

    1.1介绍set - C++ Reference

    1.2set的使用

    1. set的模板参数列表

     2.set构造

     3.常用接口

    1.3multiset

    2.map  

    2.1关联式容器,键值对

    2.2map的介绍 map - C++ Reference

    2.3map的常用接口 

    1.insert

    2. operator[]

    3.erase等

    4.multipmap


    1.set

    1.1介绍set - C++ Reference

    1.set是按照一定次序存储元素的容器。
    2.set在底层是用二叉搜索树(红黑树)实现的。
    3. set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
    set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
    注意:
    1. 与map/multimap不同,map/multimap中存储的是真正的键值对,set中只放
    value,但在底层实际存放的是由构成的键值对,插入元素时,只需要插入value即可。
    2.set中的元素不可以重复,元素默认按照小于来比较 ,使用set的迭代器遍历set中的元素,可以得到有序队列。

    1.2set的使用

    1. set的模板参数列表

     2.set构造

    3.常用接口

     直接查找某个值

    支持插入一段区间,一个值,具体某个位置上插入(很少用)

     删除一段区间,某个位置上的值,一个值 

    返回元素个数

    1. void test1()
    2. {
    3. set<int> s;
    4. s.insert(3);
    5. s.insert(8);
    6. s.insert(2);
    7. s.insert(1);
    8. s.insert(1);
    9. s.insert(6);
    10. s.insert(9);
    11. s.insert(1);
    12. s.insert(9);
    13. set<int>::iterator it = s.begin();
    14. while (it != s.end())//进行排序,去重
    15. {
    16. cout << *it << " ";
    17. it++;
    18. }
    19. }
    1. set<int>::iterator pos = s.find(4);
    2. if (pos != s.end())
    3. {
    4. cout << "set.find找到了" << endl;
    5. }
    6. else
    7. {
    8. cout << "未找到" << endl;
    9. }
    10. cout << s.erase(3) << endl;//删除返回元素的个数
    11. cout << s.erase(20) << endl;//失败返回0
    12. pos = s.find(100);
    13. //s.erase(pos); //这样删除不存在的数会报错
    14. if (pos != s.end())
    15. {
    16. s.erase(pos);
    17. }
    18. if (s.count(6))//可用来判断元素是否纯在
    19. {
    20. cout << "6存在" << endl;
    21. }

    结果:

    lower_bound:返回大于等于val的值

    upper_bound:返回大于val的值

     例如:

    1. void test2()
    2. {
    3. set<int> s;
    4. s.insert(2);
    5. s.insert(4);
    6. s.insert(1);
    7. s.insert(6);
    8. for (auto& ch : s)
    9. {
    10. cout << ch << " ";
    11. }
    12. cout << endl;
    13. set<int>::iterator lowit = s.lower_bound(2);//返回>=2位置的迭代器
    14. set<int>::iterator upit = s.upper_bound(5);//返回>5位置的迭代器
    15. s.erase(lowit, upit);//左闭右开。刚好把[2-5]间的值删除
    16. for (auto& ch : s)
    17. {
    18. cout << ch << " ";
    19. }
    20. cout << endl;
    21. }

     结果:

     

    1.3multiset

     介绍:与set类似,但可存储相同值的元素

    1. void test3()
    2. {
    3. multiset<int> s;
    4. s.insert(2);
    5. s.insert(4);
    6. s.insert(3);
    7. s.insert(8);
    8. s.insert(8);
    9. s.insert(8);
    10. s.insert(12);
    11. s.insert(3);
    12. s.insert(7);
    13. s.insert(5);
    14. for (auto& ch : s)
    15. {
    16. cout << ch << " ";
    17. }
    18. cout << endl;
    19. cout << s.erase(8) << endl;//会把8全部删除,返回删除的元素个数
    20. cout <<"3的个数:" << s.count(3) << endl;//返回查找的元素个数
    21. for (auto& ch : s)
    22. {
    23. cout << ch << " ";
    24. }
    25. }

    结果:

    2.map  

    2.1关联式容器,键值对

    介绍:

    1. STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,
    2. 这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。
    3. 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的
    4. 键值对,在数据检索时比序列式容器效率更高。
    1. 键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key
    2. 表键值,value表示与key对应的信息

    2.2map的介绍 map - C++ Reference

    1. map 是关联容器,它按照特定的次序 ( 按照 key 来比较 ) 存储由键值 key 和值 value 组合而成的元
    素。
    2. map 中,键值 key 通常用于排序和唯一地标识元素,而值 value 中存储与此键值 key 关联的
    内容。键值 key 和值 value 的类型可能不同,并且在 map 的内部, key value 通过成员类型
    value_type 绑定在一起,为其取别名称为 pair。
    3. map 通常被实现为二叉搜索树 ( 更准确的说:平衡二叉搜索树 ( 红黑树 ))
    4.map 中的 key 是唯一的,并且不能被修改。
    5. 支持 [] 操作符, operator[] 中实际进行插入查找。

    1. key: 键值对中key的类型
    2. T: 键值对中value的类型
    3. Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比
    4. 较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户
    5. 自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
    6. Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
    7. 空间配置器

    2.3map的常用接口 

    大部分与set是类似的,不过多介绍。

    1.insert

     make_pair是一个函数模板

     举例:

    1. void test3()
    2. {
    3. map<string, string> m;
    4. m.insert(pair<string, string>("sort", "排序"));
    5. pair<string, string> kv("insert", "插入");
    6. m.insert(kv);
    7. m.insert(make_pair("left", "左边"));
    8. m.insert(make_pair("English", "英语"));
    9. map<string, string>::iterator it = m.begin();
    10. while (it != m.end())
    11. {
    12. cout << it->first << "-" << it->second << " ";
    13. ++it;
    14. }
    15. cout << endl;
    16. for (auto& ch : m)
    17. {
    18. cout << ch.first << "-" << ch.second << " ";
    19. }
    20. cout << endl;
    21. }

    结果:按key类型进行排序

     insert的返回值:是一个pair,插入成功,iterator是指向新插入元素的迭代器,bool为true;插入失败,iterator是当前元素的的迭代器,bool为false

     例如:

    1. void test4()
    2. {
    3. string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
    4. mapint> countMap1;
    5. for (auto& str : arr)//统计水果的个数
    6. {
    7. mapint>::iterator it = countMap1.find(str);
    8. if (it != countMap1.end())
    9. {
    10. it->second++;
    11. }
    12. else
    13. {
    14. countMap1.insert(make_pair(str, 1));
    15. }
    16. }
    17. mapint> countMap2;
    18. for (auto& str : arr)
    19. {
    20. pairint>::iterator, bool> ret = countMap2.insert(make_pair(str, 1));
    21. if (ret.second == false)
    22. {
    23. ret.first->second++;
    24. }
    25. }
    26. for (auto& ch : countMap1)
    27. {
    28. cout << ch.first << "-" << ch.second << " ";
    29. }
    30. cout << endl;
    31. for (auto& ch : countMap2)
    32. {
    33. cout << ch.first << "-" << ch.second << " ";
    34. }
    35. cout << endl;
    36. }

    结果:

    2. operator[]

     源码实现类似于:

    1. mapped_type& operator[] (const key_type& k)
    2. {
    3. pairbool> ret = insert(make_pair(k, mapped_type()));
    4. //return (*(ret.first)).second;
    5. return ret.first->second;//返回的是第二个参数的引用,可以修改
    6. }

     mapped_type是第二个参数的类型,上面是构造的匿名对象。

    可充当查找,修改,插入的功能

    如果插入数据成功(返回的是插入新元素的第二个参数的引用),如果数据存在,返回的是该数据的第二个参数的引用,也可以把它修改。

    举例:

    1. void test5()
    2. {
    3. string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
    4. mapint> countMap;
    5. for (auto& str : arr)
    6. {
    7. countMap[str]++;
    8. }
    9. for (auto& ch : countMap)
    10. {
    11. cout << ch.first << "-" << ch.second << " ";
    12. }
    13. cout << endl;
    14. map m;
    15. m.insert(make_pair("suffer", "痛苦"));
    16. m.insert(make_pair("extend", "扩大"));
    17. m.insert(make_pair("left", "左边"));
    18. m["suffer"] = "遭受";//查找+修改
    19. m["right"] = "右边";//插入新数据
    20. for (auto& ch : m)
    21. {
    22. cout << ch.first << "-" << ch.second << " ";
    23. }
    24. cout << m["extend"] << endl;//查找该数据
    25. }

     结果:

     3.erase等

    1. void test6()
    2. {
    3. string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
    4. map<string, int> m;
    5. for (auto& str : arr)
    6. {
    7. m[str]++;
    8. }
    9. m.erase("苹果");
    10. for (auto& ch : m)
    11. {
    12. cout << ch.first << "-" << ch.second << " ";
    13. }
    14. }
    15. 结果:
    16. -1 西瓜-1 西红柿-1 香蕉-2

    其余接口与set也是类似的,这里不再叙述

    4.multipmap

    介绍:支持插入相同元素,其余与map是类似的,但不支持[].

  • 相关阅读:
    将多个 TransformerEncoderLayer 层堆叠起来,形成一个完整的 Transformer 编码器
    野火霸天虎 STM32F407 学习笔记_5 按键输入;位带操作介绍
    人体神经网络的应用领域,神经网络生活中的应用
    随机过程理论知识(七)
    Linux环境编程
    Ceph — 简介
    C# 中的反射机制
    python作业
    ISCSLP 2022 | AccentSpeech—从众包数据中学习口音来构建目标说话人的口音语音合成系统
    Linux14 -- 进程间通信、管道
  • 原文地址:https://blog.csdn.net/m0_64397669/article/details/126235802