zoukankan      html  css  js  c++  java
  • 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 迭代器
  • 相关阅读:
    Byteart Retail V3 全新的面向.NET与领域驱动设计的企业应用实践案例
    算法设计和数据结构学习堆排序
    OutputCacheProvider OutputCache的一点点认识
    使用beetle简单地实现高效的http基础服务
    The IoC container
    使用Visual Studio 2010进行UI自动化测试
    PortalBasic Java Web 应用开发框架 v2.6.1(源码、示例及文档)
    发展中的 CSS3
    C#数据结构与算法揭秘十
    Sql Server Profiler跟踪查询
  • 原文地址:https://www.cnblogs.com/xiongxuanwen/p/4290097.html
Copyright © 2011-2022 走看看