• C++:map与set简析


    目录

    set:

    一:什么是set

    二:举例

    set的find:

    set的erase:

    set中的count:

     set中的lower_bound

     set中的upper_bound

     multiset:

    map:

    一:什么是map

    二:函数与[]


    set:

    一:什么是set

    set 翻译为集合,是一个内部自动有序且不含重复元素的容器,加入 set 之后可以实现自动排序。

    简单来说就是去重+排序(默认从小到大)

    二:举例

    我们插入多个数字1,并且打乱1-5的顺序

    1. int main()
    2. {
    3. set s;
    4. s.insert(1);
    5. s.insert(1);
    6. s.insert(1);
    7. s.insert(1);
    8. s.insert(1);
    9. s.insert(5);
    10. s.insert(4);
    11. s.insert(2);
    12. s.insert(3);
    13. auto it = s.begin();
    14. while (it != s.end())
    15. {
    16. cout << *it << " ";
    17. it++;
    18. }
    19. cout << endl;
    20. return 0;
    21. }

    结果如下:set就实现了去重+排序

     

     三:一些简单的函数用法和简析

    set的find:

    find函数的用法和set一样,我们就以前面为例,找数字2

    auto pos = s.find(2);

    但是我们同样知道算法中也有一个find函数

    auto pos = find(s.begin(), s.end(), 2);

     那么他们究竟有什么区别?

    算法中的find是暴力查找,是遍历整个区间,所以时间复杂度是O(N);

    而set中的find利用了搜索树的特性,时间复杂度是O(longN);

    所以在数据量非常大的时候,set函数就用自己自带的find函数就行了

    set的erase:

    这里erase和find结合起来使用

    以上面为例,假如我要删除

    1. int x;
    2. while (cin >> x)//输入要删除的值
    3. {
    4. auto pos = s.find(x);//接收
    5. if (pos != s.end())
    6. {
    7. s.erase(pos);//删除
    8. cout << "删除" << x << "成功" << endl;
    9. }
    10. }

     有些同学会说,我们不能直接放在外面吗?

    1. s.insert(3);
    2. s.erase(3);//放在这里不行吗??????
    3. int x;
    4. while (cin >> x)//输入要删除的值
    5. {
    6. auto pos = s.find(x);//接收
    7. if (pos != s.end())
    8. {
    9. s.erase(pos);//删除
    10. cout << "删除" << x << "成功" << endl;
    11. }
    12. }

     答案是不行的。

    如果我们这个数据中如果没有对应的值,假如我们在这里删除3

    1. S.insert1);
    2. S.insert2);
    3. S.erase(3);

     那么编译器就会报错

     如果我们判断了,没有这个数再进行删除,那么就不会报错了,所以说判断是很重要的不能省略。

    同时如果删除成功,这里返回1,删除失败返回0

    1. s.inser(3);
    2. cout << s.erase(3) << endl;
    3. cout << s.erase(30) << endl;

     

    set中的count:

    count函数的功能类似于find但是比find更简单

     

    1. s.insert(3);
    2. if(s.count(3))
    3. {
    4. cout<<"在"<<endl;
    5. }

     如果在,返回1,如果不在返回0

    结果如下

     set中的lower_bound

    返回大于等于的值

    举例:我插入1-5,7,9.然后用lower_bound找3和6,3可以直接找到,但是6没有,所以返回>=6最近的元素7.

    1. set s;
    2. s.insert(1);
    3. s.insert(2);
    4. s.insert(3);
    5. s.insert(4);
    6. s.insert(5);
    7. s.insert(7);
    8. s.insert(9);
    9. auto it = s.lower_bound(3);
    10. cout << *it << endl;
    11. it = s.lower_bound(6);
    12. cout << *it << endl;

    结果如下:

     

     set中的upper_bound

    与lower_bound的大于等于,upper_bound返回大于

    相当于lower是闭区间,而upper是开区间

    验证如下:还是1-5,然后7,9

    1. set s;
    2. s.insert(1);
    3. s.insert(2);
    4. s.insert(3);
    5. s.insert(4);
    6. s.insert(5);
    7. s.insert(7);
    8. s.insert(9);
    9. auto it = s.upper_bound(3);
    10. cout << *it << endl;
    11. it = s.upper_bound(6);
    12. cout << *it << endl;

     结果如下:

    此时虽然队列中有3,但是upper是返回比3更大值的最近的一个,所以返回了4 

     multiset:

    允许同一个数据的插入

    1. multiset s;
    2. s.insert(1);
    3. s.insert(1);
    4. s.insert(1);
    5. s.insert(2);

    结果如下: 

     

    map:

    一:什么是map

    map是STL的一个关联容器,它提供一对一的hash。

    map有两个,一个被称为关键字key,另一个被称为关键字的值value

    举一个例子:我定义了一个map的对象dict,然后在dict里面插入了一个关键字left

    然后左边,是对left给的值

    然后输出

    1. map dict;
    2. dict.insert(make_pair("left", "左边"));
    3. auto it = dict.begin();
    4. while (it != dict.end())
    5. {
    6. cout << it->first <->second<< " ";
    7. it++;
    8. }
    9. cout << endl;

    •  

    结果如下:

     

    二:函数与[]

    map中的insert插入:

    对于insert我们有三种插入的写法,但是我们一般使用第三种,因为第三种方便

    1. // 定义一个map对象
    2. map<string, string> dict;
    3. // 第一种 用insert函數插入pair
    4. mapStudent.insert(pair<int, string>("left", "左边"));
    5. // 第二种 用insert函数插入value_type数据
    6. mapStudent.insert(map<int, string>::value_type("left", "左边"));
    7. // 第三种 用"make_pair"方式插入
    8. dict.insert(make_pair("left", "左边"));

    []:

    map的[]与vector和string等不一样,[]的方括号一般用来统计

    1. string arr[] = { "苹果","西瓜","苹果","西瓜" ,"苹果" };
    2. map<string, int> countMap;
    3. for (auto& str : arr)
    4. {
    5. countMap[str]++;
    6. }
    7. auto it = countMap.begin();
    8. while (it != countMap.end())
    9. {
    10. cout << it->first << ":" << it->second << " " << endl;
    11. it++;
    12. }

    结果如下:

     在库中是这样实现的

    1. mapped_type& operator[](const key_type&k)
    2. {
    3. return (*((this->insert(make_pair(k,mapped_type()))).first)).second;
    4. }

    简化一下就是这样

    1. mapped_type& operator[](const key_type&k)
    2. {
    3. pairbool>ret=insert(make_pair(k,mapped_type()));
    4. return ret.first->second;
    5. }

  • 相关阅读:
    小米商城侧边栏【显示向右箭头】
    等比例缩放
    软件提示vcruntime140_1.dll丢失的解决方法,以及丢失的原因总结
    【工程光学】光度学&色度学
    pytest功能特性介绍
    MyBatis-XML映射文件
    一文搞懂drag&drop浏览器拖放功能的实现
    notepad++编辑多个位置
    iNFTnews|Web3正在重新定义粉丝的意义
    flex布局与float布局
  • 原文地址:https://blog.csdn.net/qq_62718027/article/details/126165599