• C++ map和set(补充)


    目录

    1.set

     简单使用

     set的迭代器

     set的find  

     set的erase

    set的lower_bound和upper_bound

    std::multiset

    练习题:两个数组的交集

    2.map

    map的访问及其遍历

    使用map统计次数

    *练习题:前k个高频单词


    1.set

     简单使用

    插入1后存在去重效果 

     范围for同样支持

     set的迭代器

    普通迭代器和const迭代器都不支持修改

     源码中普通迭代器和const迭代器用的是同一个

     set的find  

    使用全局的find查找? 

     前者时间复杂度O(logn),后者的时间复杂的是O(n),即暴力查找

     std::find算法的源码

     set的erase

     

     使用erase的前提是set中需要用需要删除的数据,如果没有找到需要删除的数据,使用erase时会出现报错

     

     判断数据存在的两种方式

    1. if (s.count(5))
    2. {
    3. cout << "5存在" << endl;
    4. }
    5. if (s.find(5) != s.end())
    6. {
    7. cout << "5存在" << endl;
    8. }

    set的lower_bound和upper_bound

     调试可知,返回3所在位置的迭代器,set中没有6时返回7所在位置的迭代器。

     综上,返回>=val的位置迭代器

     upper_bound的使用:返回>x位置的迭代器

    使用lower_bound和upper_bound删除区间值。前者返回区间的[ ,后者返回区间的)。

    std::multiset

    不去重排序,其函数接口和set基本保持一致

     使用erase时会删除所有相同的数据

    有多个相同的值时使用find会返回哪一个呢?以find(3)为例子,返回中序的第一个3

    练习题:两个数组的交集

    力扣

    1. class Solution {
    2. public:
    3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    4. set<int> s1;
    5. for(auto e:nums1)
    6. {
    7. s1.insert(e);
    8. }
    9. vector<int> v;
    10. for(auto e :nums2)
    11. {
    12. if(s1.count(e))
    13. v.push_back(e);
    14. }
    15. return v;
    16. }
    17. };

     未通过的原因:没有去重。改正为下面代码即可

    1. class Solution {
    2. public:
    3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    4. //去重
    5. set<int> s1;
    6. for(auto e:nums1)
    7. {
    8. s1.insert(e);
    9. }
    10. //去重
    11. set<int> s2;
    12. for(auto e :nums2)
    13. {
    14. s2.insert(e);
    15. }
    16. //时间复杂度N*logN
    17. vector<int>v;
    18. for(auto e1:s1)
    19. {
    20. if(s2.count(e1))
    21. v.push_back(e1);
    22. }
    23. return v;
    24. }
    25. };

    改进思路如下 

    1. class Solution {
    2. public:
    3. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    4. //去重
    5. set<int> s1;
    6. for(auto e:nums1)
    7. {
    8. s1.insert(e);
    9. }
    10. //去重
    11. set<int> s2;
    12. for(auto e :nums2)
    13. {
    14. s2.insert(e);
    15. }
    16. vector<int>v;
    17. auto it1 = s1.begin();
    18. auto it2 = s2.begin();
    19. while(it1 != s1.end()&&it2 != s2.end())
    20. {
    21. if(*it1<*it2)
    22. {
    23. ++it1;
    24. }
    25. else if(*it1 > *it2)
    26. {
    27. ++it2;
    28. }
    29. else
    30. {
    31. v.push_back(*it1);
    32. ++it1;
    33. ++it2;
    34. }
    35. }
    36. return v;
    37. }
    38. };

    2.map

    map的访问及其遍历

    整体的返回值是迭代器节点里面的数据,节点里面的数据是一个pair。此处编译报错说明pair不支持流插入

     改正如下即可

     也可使用重载的箭头,重载的箭头返回数据的指针,数据的指针是一个pair*,pair*再加一个箭头就可以访问first和second

     也可使用范围for遍历

    使用map统计次数

     通过对于insert的理解,可以对上述代码进行改进

     insert有一个返回值返回pair,返回pair后pair::first被设置为一个迭代器。该迭代器要么指向新插入的元素,或者没有插入成功(map中可能存在相同元素),指向已经存在的相同的元素所在的位置

    second是一个布尔值,如果新插入了元素就是true,如果已经存在和新插入的元素相等的元素,就是false。

     

     使用operator[]改进如下

     

    以插入中英文为例使用operator[]

     

     

     

    *练习题:前k个高频单词

    力扣

     

  • 相关阅读:
    P1091 [NOIP2004 提高组] 合唱队形
    Java面试题之多态
    XJ+Nreal 高精度地图+Nreal眼镜SDK到发布APK至眼镜中
    sync.Pool:提高Go语言程序性能的关键一步
    pom文件中引入本地jar包到maven项目
    C#【自动化测试】对Windows桌面应用程序进行UI自动化测试
    数据开发流程及规范
    6.0、软件测试——判定表法
    第一百三十八回 如何在图标旁边添加小红点
    深圳市工业和信息化局5G产业发展扶持计划操作规程
  • 原文地址:https://blog.csdn.net/m0_61548909/article/details/126085923