关联容器复习

  1. 关联容器和顺序容器的不同点
    • 关联容器是基于关键字的。关键字决定了值存储的位置,也决定了访问的时候到哪里去找到。关键字起到的是索引的作用。似乎是废话。
  2. 关联容器包括有
    - 按照关键字有序保存 set,map,multiset, multimap,
    - 无序集合,通过哈希表来实现 unordered_map, unordered_set, unnordered_multiset, unordered_multimap.
  3. set和map的作用:
    • set的值只有一个关键字,常常用来知道一个元素是否在set中存在。是const的
    • map的value_type 是一个pair,也就是一个键值对。pair有两个元素,一个first,一个second。first是const的。map常常用来统计。
  4. set和map的初始化
    1. 可以使用** {} **来赋初值。也可以使用构造函数,比如在括号里是另外一个set或者map,或者使用另外一个容器的begin和end指针,来进行初始化。
  5. set和map的关键字要求
    1. set和map是关联容器,是基于关键字的。对于关键字也是有要求的,不是随意定义一种数据类型就可以作为关键字。
    2. 有序容器,也就是不带unordered的数据类型,是需要关键字可以使用<来定义大小关系的。
    3. 对于有序容器的这种要求,我们采用一个函数类型(用来完成比较任务)来满足这种需求。就是在定义map/set的时候,在<>中元素后面传入另外一个类型:自定义操作类型。可以使用decltype(函数名)*来指明。
  6. pair类型
    1. pair类型是map的value_type, 其也是一个模板类。为标准库的一部分,在< unility > 文件中
    2. pair包括两个公开成员变量。一个是first,一个是second。
    3. pair对象的初始化操作,使用
      • pair<T1, T2> p(v1, v2)
      • 使用初始化器
      • 使用make_pair
    4. pair的公开成员变量可以直接访问。
    5. pair定义了关系运算符。 == != >= 等
    6. 再pair作为返回值返回的时候,可以使用 { v1, v2 }。也就是使用初始化列表来构建一个匿名的pair,返回。再早期的c++里面不允许这样做。也可以使用make_pair()来进行返回。
  7. 关联容器的基本操作
    1. 关联容器数据类型有key_type, mapped_type, value_type三种,可以使用作用域运算符来进行提取。

    2. 关联容器的迭代器也是这个类型空间的,名字叫做 iterator。迭代器有const iterator(相当于常量指针)和iterator。但是由于set和map的关键字都是const的,实际上都不可以更改。但是iterator可以更改pair的second值。但是const iterator不可以更改。两者都可以更改指针本身的值。也就是可以通过 ++ 完成遍历操作。

    3. 关联容器可以适用于哪些算法
      泛型算法不适用。其不适用于需要修改,重排元素的值的算法。因为元素中有const修饰。搜索算法似乎也效率不高,如果需要的话,可以将值腾出来。

    4. 添加一个元素

      • set添加
        我们使用insert添加元素。有两个版本的insert,可以是一对迭代器,也可以是一个初始化列表。也就是说,可以一次插入多个值。
      • map添加
        每次insert,参数必须是一个pair,不可以是多个pair。pair的临时制作前面说过,可以使用 {} ,也可以使用make_pair,或者使用初始化方法。返回值为一个pair。first为插入的指针,也就是迭代器。second为是否成功插入。再map中,当关键字已经存在,会失败,没有任何影响。再multimap中,总会成功。
    5. 删除一个元素
      使用erase函数。这个函数有三个版本。1 参数为一个迭代器,表示删除指定元素,返回值为void。 2 参数为一个迭代器对,表示删除指定区间的元素,返回值为void (这两个很像顺序容器) 3 参数为一个key_type 类型的值,表示删除key_type为指定的元素。返回删除的个数。对于非multi 为0或者1.对于multi,>=0

    6. map下标操作
      map支持下标操作,还有at函数,里面内容都是关键字内容。at()当对应元素不存在,会抛出异常。而下标操作如果没有的话,会创建一个,并进行初始化。这和顺序容器的下标操作大不相同。因此想要知道一个元素是否再map中,千万不要用下标操作。
      map的下标操作返回值为一个mapped_tyoe类型的值。并且是一个左值,可以进行写操作。

    7. 查找元素信息
      由于map的下标操作不可以用来仅仅测试一个元素是否存在。我们使用count操作或者find操作来仅仅检查是否存在。count()用来数一数有多少个符合元素,返回int 出现的次数。如果为0,说明未出现。find()用来返回一个指向这个元素的迭代器。没有的话,返回.end()迭代器。
      可以使用lower_bound() 和 upper_bound() 来返回一个迭代器范围,打印出在multi中的所有我们需要查找的元素,如果不存在就指向相同的指针,则不打印。

    8. 无序容器
      特点就是: 使用哈希函数和关键字类型的 == 运算符来确定元素的位置。适用于关键字类型本身就是无序的情况 或者 使用有序容器发现性能比较低的情况下。
      无序容器的原理就是 一组桶 。通过哈希函数将元素映射到相应的桶里面。允许一个桶里面有多个元素。
      由于标准库里面已经对基本数据类型和其他的常用类进行了hash的适配。可以直接使用。但是对于自定义的类型,想要作为关键字,必须要有相当于 == 和 hash运算的部分。我们采用函数来实现。由于其他类型的hash运算是通过hash< type >来实现的,我们可以使用一个函数来利用这个hash来实现我们自己的hash。至于比较操作就也是实现一个函数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值