map和set相关api记录

set和map属于关联容器。其他多属于顺序容器。关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。

在不用到set/map的排序时,建议使用unordered_set/unordered_map(C++11),其速度要比set/map快的多

map

下面是对文章中介绍map用法的一些照搬

  • map的使用

    1
    2
    #include<map>
    std::map<int, string> mapStudent;
  • 访问map中的元素

    可以直接通过m[key]进行访问

  • map插入一个元素

    1
    2
    3
    4
    5
    6
    // 最简单的一种
    mapStudent.insert({1, "student_first"});
    // 1. 插入,用insert函数插入pair数据
    mapStudent.insert(pair<int, string>(1, "student_one"));
    // 2. 用insert函数插入value_type数据
    mapStudent.insert(map<int, string>::value_type (2, "student_two"));

    当map中这个关键字时,insert操作是插入不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值

    检验插入是否成功

    1
    2
    3
    4
    5
    6
    7
    pair<map<int, string>::iterator, bool> Insert_Pair;  
    Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));

    if(Insert_Pair.second == true)
    cout<<"Insert Successfully"<<endl;
    else
    cout<<"Insert Failure"<<endl;
  • map更改元素的值

    1
    2
    // 通过数组形式更新元素
    mapStudent[3] = "student_three";
  • map遍历所有的元素

    1
    2
    3
    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
    cout<<iter->first<<' '<<iter->second<<endl;
    // 判断map的大小,也可以使用 mapStudent.size()
  • 查找并获取map中的元素

    • 使用find()函数,传入要查找的key

      1
      2
      3
      4
      5
      6
      map<int, int> m;
      m.insert({1, 23});
      map<int, int>::iterator iter;
      iter = m.find(1);
      if(iter != m.end())
      cout<<"find the item whose key is 1\n";
    • find_if()的使用

      1
      2
      3
      4
      5
      6
      template<class InputIterator, class Predicate>
      InputIterator find_if ( InputIterator first, InputIterator last, Predicate pred )
      {
      for ( ; first!=last ; first++ ) if ( pred(*first) ) break;
      return first;
      }

      它在区间[first,end)中搜寻使一元判断式pred为true的第一个元素。

      如果没找到,返回end

      我们只需要填入参数,这是一个封装好的函数

      pred函数要有返回值

  • 从map中删除数据

    1
    2
    3
    4
    5
    6
    7
    8
    iterator erase(iterator it);//通过一个条目对象删除

    iterator erase(iterator first,iterator last)//删除一个范围

    size_type erase(const Key&key);//通过关键字删除
    int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0

    clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());
  • map中的swap用法

    map中的swap不是一个容器中的元素交换,而是两个容器所有元素的交换。

  • 排序 · map中的sort问题

    map中的元素是自动按Key升序排序,所以不能对map用sort函数

    这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。

set

set是一个容量动态变化的容器(使用了红黑树)【只能通过遍历访问子元素,不能通过索引,但可以使用find】,且系统会为其储存元素按递增排序;

  • 如果存入自定义结构,可以重写<、>操作符
  • 常见操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    begin();            // 返回指向第一个元素的迭代器
    end(); // 返回指向最后一个元素的迭代器
    clear(); // 清除所有元素
    count(); // 返回某个值元素的个数
    empty(); // 如果集合为空,返回true
    equal_range(); // 返回集合中与给定值相等的上下限的两个迭代器
    erase() // 删除集合中的元素
    find() // 返回一个指向被查找到元素的迭代器
    get_allocator() // 返回集合的分配器
    insert() // 在集合中插入元素
    // set中进行插入的insert函数。其实这个函数是有返回值的,只不过我们不常用。它的返回值是一个pair,first成员就是指向新插入的元素在set中位置的迭代器,second成员是一个bool表示这次插入操作是否成功。
    lower_bound() // 返回指向大于(或等于)某值的第一个元素的迭代器
    key_comp() // 返回一个用于元素间值比较的函数
    max_size() // 返回集合能容纳的元素的最大限值
    rbegin() // 返回指向集合中最后一个元素的反向迭代器
    rend() // 返回指向集合中第一个元素的反向迭代器
    size() // 集合中元素的数目
    swap() // 交换两个集合变量
    upper_bound() // 返回大于某个值元素的迭代器
    value_comp() // 返回一个用于比较元素间的值的函数