C++ Primer(第4版)-学习笔记-第2部分:容器和算法

第9章 顺序容器
  1. 顺序容器和关联容器
    顺序容器内的元素按其位置存储和访问。
    关联容器,其元素按键(key)排序。

  2. 顺序容器(sequential container)。
    顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。 

  3. 标准库定义了三种顺序容器类型:vector、list 和 deque(是双端队列“double-ended queue”的简写,发音为“deck”)。
    头文件如下:
    #include <vector>
    #include <list>
    #include <deque> 

  4. 标准库还提供了三种容器适配器(adaptors)。适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型。
    顺序容器适配器包括 stack、queue 和 priority_queue 类型。

  5. 顺序容器
    vector 支持快速随机访问,支持下标访问 ,但在中间随机插入/删除速度慢
    list   支持快速插入/删除,不支持随机访问。
    deque   双端队列
     
    顺序容器适配器
    stack
    后进先出(LIFO)堆栈
    queue 
    先进先出(FIFO)队列
    priority_queue 
    有优先级管理的队列 
  6. 所有的容器都是类模板:
    vector<string>    svec;       // empty vector that can hold strings
    list<int>         ilist;      // empty list that can hold ints
    deque<Sales_item> items;      // empty deque that holds Sales_items 

  7. 容器元素的初始化(构造函数)
    容器类型最常用的构造函数是默认构造函数。在大多数的程序中,使用默认构造函数能达到最佳运行时性能,并且使容器更容易使用。
    C<T> c; 创建一个名为 c 的空容器。C 是容器类型名,如 vector,T 是元素类型,如 int 或 string 适用于所有容器
    C c(c2);  创建容器 c2 的副本 c;c 和 c2 必须具有相同的容器类型,并存放相同类型的元素。适用于所有容器。要求容器类型和容器里元素的类型都必须相同。
    C c(b, e); 创建 c,其元素是迭代器 b 和 e 标示的范围内元素的副本。适用于所有容器。不要求容器类型相同,容器里元素类型也可以不相同,相互兼容即可。
    C c(n, t);      用 n 个值为 t 的元素创建容器 c,其中值 t 必须是容器类型 C 的元素类型的值,或者是可转换为该类型的值。 只适用于顺序容器。
    C c(n); 创建有 n 个值初始化(第 3.3.1 节)(value-initialized)元素的容器 c。 只适用于顺序容器。
     
  8. 将一个容器初始化为另一个容器的副本。 
    vector<int> ivec;
    vector<int> ivec2(ivec);   // ok: ivec is vector<int> 
    将一个容器复制给另一个容器时,容器类型元素类型都必须相同。 

  9. 初始化为一段元素的副本。
    不能直接将一种容器内的元素复制给另一种容器,但允许通过传递一对迭代器间接实现该实现该功能。
    使用迭代器时,不要求容器类型相同,容器内的元素类型也可以不相同,只要它们相互兼容,能够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制。 
    list<string> slist(svec.begin(), svec.end());

    指针就是迭代器,因此允许通过使用内置数组中的一对指针初始化容器。
    char *words[] = {"stately", "plump", "buck", "mulligan"};
    size_t words_size = sizeof(words)/sizeof(char *);
    list<string> words2(words, words + words_size); 

  10. 分配和初始化指定数目的元素
    创建顺序容器时,可显式指定容器大小和一个(可选的)元素初始化式。容器大小可以是常量或非常量表达式,元素初始化则必须是可用于初始化其元素类型的对象的值:
    const list<int>::size_type list_size = 64;
    list<string> slist(list_size, "eh?"); // 64 strings, each is eh?
    这段代码表示 slist 含有 64 个元素,每个元素都被初始化为“eh?”字符串。
    也可以只指定容器大小: 
    list<int> ilist(64); // 64 elements, each initialized to 0 

  11. 容器内元素的类型约束
    容器元素类型必须满足以下两个约束:
    •  元素类型必须支持赋值运算。
    •  元素类型的对象必须可以复制。
    关联容器的键还必须支持“<”操作符。

  12. 容器的容器
    可定义元素是容器类型的容器:vector< vector<string> > lines; //必须用空格隔开两个相邻的 > 符号。

  13. 常用迭代器的运算
    *iter                                返回迭代器 iter 所指向的元素的引用 
    iter->mem 对 iter 进行解引用,获取指定元素中名为 mem 的成员。等效于(*iter).mem 
    ++iter,iter++ 给 iter 加 1,使其指向容器里的下一个元素 
    --iter,iter-- 给 iter 减 1,使其指向容器里的前一个元素
    iter1 == iter2,
    iter1 != iter2
    比较两个迭代器是否相等(或不等)。当两个迭代器指向同一个容器中的同一个元素,或者当它们都指向同一个容器的超出末端的下一位置时,两个迭代器相等 
     
  14.  vector 和 deque 容器的迭代器独有支持:迭代器算术运算:iter + n , iter - n , iter1 += iter2, iter1 -= iter2,  
    除了 == 和 != 之外的关系操作符来: > , >=, < , <=

  15. list迭代器不支持算术运算,也不支持关系元算,只支持:++iter, iter++ 和 iter1 == iter2, iter1 != iter2 。

  16. 迭代器范围:左闭合区间
    [ first, last) : 表示范围从 first 开始,到 last 结束,但不包括 last。
    1).  当 first 与 last 相等时,迭代器范围为空;
    2).  当 first 与不相等时,迭代器范围内至少有一个元素,而且 first 指向该区间中的第一元素。此外,通过若干次自增运算可以使 first 的值不断增大,直到 first == last 为止。 

  17. 容器定义的类型
    size_type 无符号整型,足以存储此容器类型的最大可能容器长度 
    iterator   此容器类型的迭代器类型
    const_iterator   元素的只读迭代器类型
    reverse_iterator   按逆序寻址元素的迭代器 
    const_reverse_iterator   元素的只读(不能写)逆序迭代器
    difference_type 足够存储两个迭代器差值的有符号整型,可为负数 
    value_type 元素类型 
    reference 元素的左值类型,是 value_type& 的同义词 
    const_reference 元素的常量左值类型,等效于 const value_type&
     
  18. 所有容器的迭代器支持的操作: begin  和  end  成员 
    c.begin() : 返回一个迭代器,它指向容器 c 的第一个元素
    c.end() : 返回一个迭代器,它指向容器 c 的最后一个元素的下一位置 
    c.rbegin() : 返回一个逆序迭代器,它指向容器 c 的最后一个元素 
    c.rend() : 返回一个逆序迭代器,它指向容器 c 的第一个元素前面的位置

  19. 容器元素都是副本
    在容器中添加元素时,系统是将元素值复制到容器里(所以要求元素的类型必须支持复制)。类似地,使用一段元素初始化新容器时,新容器存放的是原始元素的副本。被复制的原始值与新容器中的元素各不相关,此后,容器内元素值发生变化时,被复制的原值不会受到影响,反之亦然。 

  20. 如果用容器存副本,则容器销毁的时候,副本也会自动被删除。
    如果用容器存指针,则容器销毁的时候,不会删除这些指针所指向的对象,因此必须先手工删除完毕之后,再销毁容器。

  21. 顺序容器中添加元素
    c.push_back(t)  在容器 c 的尾部添加值为 t 的元素。返回 void 类型。 
    c.push_front(t)  在容器 c 的前端添加值为 t 的元素。返回 void 类型。只适用于 list 和 deque 容器类型。
    c.insert(p,t)  在迭代器 p 所指向的元素前面插入值为 t 的新元素。返回指向新添加元素的迭代器。
    c.insert(p,n,t) 在迭代器 p 所指向的元素前面插入 n 个值为 t 的新元素。返回 void 类型 。
    c.insert(p,b,e) 在迭代器 p 所指向的元素前面插入由迭代器 b 和 e 标记的范围内的元素。返回 void 类型。
  22. 添加元素可能会使迭代器失效
    任何 insert 或 push 操作都可能导致某些或所有迭代器失效。当编写循环将元素插入到 vector 或 deque 容器中时,程序必须确保迭代器在每次循环后都得到更新。 

  23. 关系操作符
    所有的容器类型都支持用关系操作符来实现两个容器的比较。相比较的容器必须具有相同的容器类型,而且其元素类型也必须相同。

  24. 顺序容器的大小操作
    c.size()  返回容器 c 中的元素个数。返回类型为 c::size_type 
    c.max_size() 返回容器 c 可容纳的最多元素个数,返回类型为c::size_type
    c.empty()  返回标记容器大小是否为 0 的布尔值 
    c.resize(n) 调整容器 c 的长度大小,使其能容纳 n 个元素,如果 n < c.size(),则删除多出来的元素;否则,添加采用值初始化的新元素 
    c.resize(n,t) 调整容器 c 的长度大小,使其能容纳 n 个元素。所有新添加的元素值都为 t 
    resize 操作可能会使迭代器失效。在 vector 或 deque 容器上做 resize 操作有可能会使其所有的迭代器都失效。
  25. 访问顺序容器内元素的操作 
    c.back() 返回容器 c 的最后一个元素的引用。如果 c 为空,则该操作未定义
    c.front() 返回容器 c 的第一个元素的引用。如果 c 为空,则该操作未定义
    c[n] 返回下标为 n 的元素的引用 如果 n <0 或 n >= c.size(),则该操作未定义。只适用于 vector 和 deque 容器
    c.at(n) 返回下标为 n 的元素的引用。如果下标越界,则该操作未定义。只适用于 vector 和 deque 容器
     使用越界的下标,或调用空容器的 front 或 back 函数,都会导致程序出现严重的错误。
     
  26. 删除顺序容器内元素的操作 
    c.erase(p) 删除迭代器 p 所指向的元素返回一个迭代器,它指向被删除元素后面的元素。如果 p 指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果 p 本身就是指向超出末端的下一位置的迭代器,则该函数未定义。
    c.erase(b,e) 删除迭代器 b 和 e 所标记的范围内所有的元素返回一个迭代器,它指向被删除元素段后面的元素。如果 e 本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置。
    c.clear()  删除容器 c 内的所有元素。返回 void。
    c.pop_back() 删除容器 c 的最后一个元素。返回 void。如果 c 为空容器,则该函数未定义。
    c.pop_front() 删除容器 c 的第一个元素,返回 void。如果 c 为空容器,则该函数未定义。只适用于 list 或 deque 容器。
  27. 顺序容器的赋值操作 
    c1 = c2 删除容器 c1 的所有元素,然后将 c2 的元素复制给 c1。c1 和c2 的类型(包括容器类型和元素类型)必须相同。
    c1.swap(c2) 交换内容:调用完该函数后,c1 中存放的是 c2 原来的元素,c2 中存放的则是 c1 原来的元素。c1 和 c2 的类型必须相同。该函数的执行速度通常要比将 c2 复制到 c1 的操作快。
    c.assign(b,e) 重新设置 c 的元素:将迭代器 b 和 e 标记的范围内所有的元素复制到 c 中。b 和 e 必须不是指向 c 中元素的迭代器 。
    c.assign(n,t)  将容器 c 重新设置为存储 n 个值为 t 的元素。
  28. 选择容器的提示
    1).  如果程序要求随机访问元素,则应使用 vector 或 deque 容器。
    2).  如果程序必须在容器的中间位置插入或删除元素,则应采用 list 容器。 
    3).  如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元素,则应采用 deque 容器。
    4).  如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑在输入时将元素读入到一个 list 容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的 list 容器复制到一个 vector 容器。 

  29. string
    string类型可以视为字符容器。除了一些特殊操作,string 类型提供与 vector 容器相同的操作。string 类型与 vector 容器不同的是,它不支持以栈方式操纵容器:在 string 类型中不能使用 front、back 和 pop_back 操作。

    string 类型提供了容器类型不支持其他几种操作:
    •  substr 函数,返回当前 string 对象的子串。
    •  append 和 replace 函数,用于修改 string 对象。
    •  一系列 find 函数,用于查找 string 对象。 

  30. string:substr 操作
    使用 substr 操作可在指定 string 对象中检索需要的子串。
    s.substr(pos, n) 返回一个 string 类型的字符串,它包含 s 中从下标 pos开始的 n 个字符
    s.substr(pos)  返回一个 string 类型的字符串,它包含从下标 pos 开始到s 末尾的所有字符 
    s.substr() 返回 s 的副本 
     
  31. append 和 replace
    s.append(args) 将 args 串接在 s 后面。返回 s 引用
    s.replace(pos, len, args)          删除 s 中从下标 pos 开始的 len 个字符,用 args 指定的字符替换之(在pos位置插入args)。返回 s 的引用 
    s.replace(b, e, args) 删除迭代器 b 和 e 标记范围内所有的字符,用 args 替换之(在pos位置插入args)。返回 s 的引用 
     
  32. string 类型的查找操作
    s.find( args)  在 s 中查找 args 的第一次出现 
    s.rfind( args) 在 s 中查找 args 的最后一次出现 
    s.find_first_of( args) 在 s 中查找 args 的任意字符的第一次出现
    s.find_last_of( args) 在 s 中查找 args 的任意字符的最后一次出现
    s.find_first_not_of( args) 在 s 中查找第一个不属于 args 的字符
    s.find_last_not_of( args) 在 s 中查找最后一个不属于 args 的字符
     
第10章 关联容器
  1. 关联容器支持通过来高效地查找和读取元素;顺序容器是通过元素在容器中的位置顺序存储和访问元素。

  2. map 的元素以键-值(key-value)对的形式组织:键用作元素在 map 中的索引,而值则表示所存储和读取的数据。
    set 仅包含一个键,并有效地支持关于某个键是否存在的查询。
    set适用于存储不同值的集合。map 容器则更适用于需要存储(乃至修改)每个键所关联的值的情况。
    map 关联数组,元素通过键来存储和读取
    set 大小可变的集合,支持通过键实现的快速读取
    multimap 支持同一个键多次出现的 map 类型
    multiset 支持同一个键多次出现的 set 类型 
     
  3. pair类型
    pair也是一种模板类型。 
    pair<T1, T2> p1;  创建一个空的 pair 对象,它的两个元素分别是 T1 和 T2 类型,采用值初始化。
    pair<T1, T2> p1(v1, v2); 创建一个 pair 对象,它的两个元素分别是 T1 和 T2 ,其中 first 成员初始化为 v1,而 second 成员初始化为 v2。 
    make_pair(v1,v2); 以 v1 和 v2 值创建一个新 pair 对象,其元素类型分别是v1 和 v2 的类型。
    p1 < p2  两个 pair 对象之间的小于运算,其定义遵循字典次序:如果 p1.first < p2.first 或者 !(p2.first < p1.first) && p1.second < p2.second,则返回 true 。
    p1 == p2   如果两个 pair 对象的 first 和 second 成员依次相等,则这两个对象相等。该运算使用其元素的 == 操作符。
    p.first  返回 p 中名为 first 的(公有)数据成员。
    p.second 返回 p 的名为 second 的(公有)数据成员 。
     
  4. 关联容器不提供front、push_front、pop_front、back、push_back以及pop_back操作;

  5. 要使用map对象,则必须包含map头文件;
    定义map对象时,必须分别指明键和值的类型。map<string, int> word_count;
    map<k, v> m;                     创建一个名为 m 的空 map 对象,其键和值的类型分别为 k 和 v
    map<k, v> m(m2);  创建 m2 的副本 m,m 与 m2 必须有相同的键类型和值类型 
    map<k, v> m(b, e);  创建 map 类型的对象 m,存储迭代器 b 和 e 标记的范围内所有元素的副本。元素的类型必须能转换为 pair<const k, v> 
     
  6. 关联容器的键类型必须支持 < 操作符,而且该操作符应能“正确地工作”;

  7. map 定义的类型
    map<K, V>::key_type                    在 map 容器中,用做索引的键的类型 
    map<K,V>::mapped_type 在 map 容器中,键所关联的值的类型 
    map<K,V>::value_type 一个 pair 类型,它的 first 元素具有 const map<K, V>::key_type 类型,而 second 元素则为 map<K, V>::mapped_type 类型 
    谨记: value_type 是 pair 类型,它的值成员可以修改,但键成员不能修改。 
  8. 给 map 添加元素
    (1) 使用insert 成员实现;
    (2) 先用下标操作符获取元素,然后给获取的元素赋值。

  9. 使用下标访问 map 对象
    使用下标[i]访问map中不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值;

  10. map::insert 的使用 
    m.insert(e) e 是一个用在 m 上的 value_type 类型的值。如果键(e.first)不在 m 中,则插入一个值为 e.second 的新元素;如果该键在 m 中已存在,则保持 m 不变。该函数返回一个 pair 类型对象,包含指向键为 e.first 的元素的 map 迭代器,以及一个 bool 类型的对象,表示是否插入了该元素。
    m.insert(beg, end)                                                                        beg 和 end 是标记元素范围的迭代器,其中的元素必须为 m.value_type 类型的键-值对。对于该范围内的所有元素,如果它的键在 m 中不存在,则将该键及其关联的值插入到 m。返回 void 类型 。
    m.insert(iter,e)  e 是一个用在 m 上的 value_type 类型的值。如果键(e.first)不在 m 中,则创建新元素,并以迭代器 iter 为起点搜索新元素存储的位置。返回一个迭代器,指向 m 中具有给定键的元素。
     
  11. 查找并读取 map 中的元素
    不修改 map 对象的查询操作:
    m.count(k)  返回 m 中 k 的出现次数
    m.find(k) 如果 m 容器中存在按 k 索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。
     
  12. 从map中删除元素
    m.erase(k)   删除 m 中键为 k 的元素。返回 size_type 类型的值,表示删除的元素个数 
    m.erase(p)  从 m 中删除迭代器 p 所指向的元素。p 必须指向 m 中确实存在的元素,而且不能等于 m.end()。返回 void 
    m.erase(b, e)                                                 从 m 中删除一段范围内的元素,该范围由迭代器对 b 和 e 标记。b 和 e 必须标记 m 中的一段有效范围:即 b 和 e 都必须指向 m 中的元素或最后一个元素的下一个位置。而且,b 和 e 要么相等(此时删除的范围为空),要么 b 所指向的元素必须出现在 e 所指向的元素之前。返回 void 类型 
  13. map 对象的迭代遍历
    与其他容器一样,map 同样提供 begin 和 end 运算,以生成用于遍历整个容器的迭代器。例如,可如下将 map 容器 word_count 的内容输出:
    map<string, int>::const_iterator  map_it = word_count.begin();
    while (map_it != word_count.end())
     {
             cout << map_it->first << " occurs "  << map_it->second << " times" << endl;
             ++map_it;

    在使用迭代器遍历map 容器时,迭代器指向的元素按键的升序排列。

  14. set
    map 容器是键-值对的集合,set 容器只是单纯的键的集合。
    两种例外包括:set 不支持下标操作符,而且没有定义 mapped_type 类型。
    在 set 容器中,value_type 不是 pair 类型,而是与 key_type 相同的类型。它们指的都是 set 中存储的元素类型。与 map 一样,set 容器存储的键也必须唯一,而且不能修改。 

  15. multimap 允许一个键对应多个实例。
    multimap不支持下标运算,因为某个键可能对应多个值;

  16. multimap添加元素
    由于键不要求是唯一的,因此每次调用 insert 总会添加一个元素。

  17. multimap 删除元素 
    带有一个键参数的 erase 版本将删除拥有该键的所有元素,并返回删除元素的个数。

  18. 在 multimap 和 multiset 中查找元素
    关联容器 map 和 set 的元素是按顺序存储的。
    在 multimap 中,同一个键所关联的元素必然相邻存放。

    方法一:使用 find 和 count 操作
    count 函数求出某键出现的次数,而 find 操作则返回一个迭代器,指向第一个拥有正在查找的键的实例:
    string search_item("Alain de Botton");
    typedef multimap<string, string>::size_type sz_type;
    sz_type entries = authors.count(search_item);
    multimap<string,string>::iterator iter = authors.find(search_item);
    for (sz_type cnt = 0; cnt != entries; ++cnt, ++iter)
        cout << iter->second << endl; // print each title 

    首先,调用 count 确定某作者所写的书籍数目,然后调用 find 获得指向第一个该键所关联的元素的迭代器。for 循环迭代的次数依赖于 count 返回的值。在特殊情况下,如果 count 返回 0 值,则该循环永不执行。

    方法二:与众不同的面向迭代器的解决方案 
    更优雅简洁的方法是使用两个未曾见过的关联容器的操作:lower_bound 和 upper_bound。
    m.lower_bound(k) 返回一个迭代器,指向键不小于 k 的第一个元素 
    m.upper_bound(k)  返回一个迭代器,指向键大于 k 的第一个元素 
    m.equal_range(k)   返回一个迭代器的 pair 对象 它的 first 成员等价于 m.lower_bound(k)。而 second 成员则等价于 m.upper_bound(k) 
    typedef multimap<string, string>::iterator authors_it;
    authors_it beg = authors.lower_bound(search_item),  end = authors.upper_bound(search_item);
    while (beg != end)

         cout << beg->second << endl; // print each title
         ++beg;
     

第11章 泛型算法
     
     每个泛型算法的实现都独立于单独的容器,并且不依赖于容器存储的元素类型。
     泛型算法需要使用迭代器,迭代器有如下要求:
        •  支持自增操作:从一个元素定位下一个元素
          •  提供解引用:访问元素的值
          •  支持相等和不等操作符:用于判断2个迭代器是否相等 
 
     “普通”的迭代器不修改基础容器的大小。算法可能会改变存储在容器中的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删除元素。 
  1. 头文件
    使用泛型算法必须包含 algorithm 头文件:
    #include <algorithm>
    标准库还定义了一组泛化的算术算法(generalized numeric algorithm),使用这些算法则必须包含 numeric 头文件:
    #include <numeric>
     
  2. 只读算法
    (1) find
    vector<int> vec;
    ...
    int search_value = 42;
    vector<int>::const_iterator result = find(vec.begin(), vec.end(), search_value); 
    内置数组也可以使用迭代器和find实现查找
    int ia[6] = {27, 210, 12, 47, 109, 83};
    int search_value = 83;
    int *result = find(ia, ia + 6, search_value); 

    (2) count
    count在容器中查找某个值出现的次数
    int cnt = count(vec.begin(), vec.end(), search_value);

    (2) accumulate
    int sum = accumulate(vec.begin(), vec.end(), 42);//将 sum 设置为 vec 的元素之和再加上 42

    (3) find_first_of
    该算法带有2段迭代器范围,在第一段范围内查找与第二段范围内任意元素匹配的元素,找到了返回第一个匹配的元素 迭代器,否则就返回第一段范围的end迭代器。

  3. 写入容器的算法
    (1) fill
    fill(vec.begin(), vec.end(), 0); // reset each element to 0

    (2) fill_n 和 back_inserter
    vector<int> vec; // empty vector
    // ok: back_inserter creates an insert iterator that adds elements to vec
    fill_n (back_inserter(vec), 10, 0); // appends 10 elements to vec

  4. 写入到目标迭代器的算法
    (1) copy
    vector<int> ivec; // empty vector
    // copy elements from ilst into ivec
    copy (ilst.begin(), ilst.end(), back_inserter(ivec));
    //copy 从输入范围中读取元素,然后将它们复制给目标 ivec。更好的方法如下:
    // better way to copy elements from ilst
    vector<int> ivec(ilst.begin(), ilst.end()); //直接初始化

    (2) replace
    //这个调用将所有值为 0 的实例替换成 42
    replace(ilst.begin(), ilst.end(), 0, 42);

    (3) replace_copy vector<int> ivec;
    replace_copy (ilst.begin(), ilst.end(),back_inserter(ivec), 0, 42);
    //调用该函数后,ilst 没有改变,ivec 存储 ilst 一份副本,而 ilst 内所有的 0 在 ivec 中都变成了 42

  5.  对容器元素重新排序的算法
    (1) sort-排序
    sort(words.begin(), words.end());//调用 sort 后,此 vector 对象的元素按次序排列

    (2) unique-删除重复元素
    vector<string>::iterator end_unique = unique(words.begin(), words.end()); 
    //该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器,表示无重复的值范围的结束。 

    (3) erase-清空指定范围内的元素
    words.erase(end_unique, words.end());

  6. 插入迭代器
    •  back_inserter,创建使用 push_back 实现插入的迭代器。
    •  front_inserter,使用 push_front 实现插入。
    •  inserter,使用 insert 实现插入操作。除了所关联的容器外,inserter 还带有第二实参:指向插入起始位置的迭代器。

  7. iostream 迭代器 
    istream_iterator 用于读取输入流,而 ostream_iterator 则用于写输出流
    istream_iterator<int> in_iter(cin); // read ints from cin
    istream_iterator<int> eof;      // istream "end" iterator
    vector<int> vec(in_iter, eof);  // construct vec from an iterator range 

  8. 反向迭代器
    rbegin 和 rend
    vector<int>::reverse_iterator r_iter;
    for (r_iter = vec.rbegin(); // binds r_iter to last element
         r_iter != vec.rend();  // rend refers 1 before 1st element
         ++r_iter)              // decrements iterator one element
    cout << *r_iter << endl;    // prints 9,8,7,...0

    以降序排列 vector,只需向 sort传递一对反向迭代器:
    // 按升序排序
    sort(vec.begin(), vec.end());
    // 按降序排序
    sort(vec.rbegin(), vec.rend());
     
  9. const 迭代器
原文地址:https://www.cnblogs.com/xiongxuanwen/p/4290097.html