理解容器和迭代器

第12章 理解容器与迭代器
------------------------------------------------------------------------------------------------------------------------------------------------------
1、迭代器(五大类):
 (1)五大类:
   读迭代器(输入迭代器)
   写迭代器(输出迭代器)
   前向迭代器
   双向迭代器
   随机访问迭代器
 (2)公共迭代器typedef和方法
   iterator、const_iterator
   reverse_iterator、const_reverse_iterator
   方法: begin()、end()  (半开区间)
    cbegin()、cend() (const)
    注:end()返回的迭代器越过了vector容器的尾部,而不是引用容器中的最后一个元素
 注:只有顺序容器、关联容器和无序关联容器提供了迭代器。容器适配器和bitset类都不支持迭代元素
------------------------------------------------------------------------------------------------------------------------------------------------------
2、C++11的变化
 (1)引入无序关联容器(散列表)
 (2)STL容器都包含了移动构造函数和移动赋值运算符,提高了性能。例如:
  原: Element myElement(12, "Twelve");
   vec.push_back(myElement);
  C++11: vec.push_back({12, "Twelve"});  //等价于 vec.push_back(Element(12, "Twelve"));
   // Or
   vec.emplace_back(12, "Twelve");
------------------------------------------------------------------------------------------------------------------------------------------------------
3、顺序容器(一):vector 容器
 (1)格式: template <class T, class Allocator = allocator<T> > class vector;
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (2)创建: 1)基本创建:  vector<double> doubleVector(10); // Create a vector of 10 doubles.
   2)指定初始值:  vector<double> doubleVector(10, 0.0); // 10 doubles of value 0.0
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (3)访问元素: operator[]运算符: 类似于数组索引,不执行边界检查
   at():   等同于operator[]运算符,但是会执行边界检查
   front():  返回第一个元素
   back():  返回最后一个元素
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (4)动态长度:    vector<double> doubleVector; // Create a vector with zero elements.
   1)push_back();  doubleVector.push_back(temp);
   2)size();  for (size_t i = 0; i < doubleVector.size(); i++) 
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (5)构造函数: 1)默认:  默认的构造函数创建一个带有0个元素的vector
      如果没有提供默认值,那么新对象通过0初始化
   3)初始化  initializer_list参数(C++11): vector<int> intVector({1,2,3,4,5,6});
      统一初始化:   vector<int> intVector = {1,2,3,4,5,6};
   4)堆分配:  vector<Element>* elementVector = new vector<Element>(10);
      delete elementVector; //通过delete(而不是delete[])释放vector,因为vector是一个基本类型,而非数组类型
   5)堆分配(使用智能指针) shared_ptr<vector<Element> > elementVector(new vector<Element>(10));
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (6)复制和赋值:1)assign();  删除所有现有的元素,添加任意数目的新元素
   2)swap();  交换两个vector的内容
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (7)迭代器:iterator:   for (vector<double>::iterator iter = doubleVector.begin();
       iter != doubleVector.end(); ++iter) 
      {
       *iter /= max;
       cout << *iter << " ";
      }
      注:1)尽量使用前递增而不要使用后递增,更为高效。因为iter++必须返回一个新的迭代器对象,而++iter只是返回对iter的引用
         2)vector迭代器是随机访问的,可以向前向后移动,而且还可以随意跳跃:--iter;
      ------------------------------------------------------------------------------------------------------
   1)使用auto关键字 for (auto iter = doubleVector.begin();
       iter != doubleVector.end(); ++iter) 
      {
       *iter /= max;
       cout << *iter << " ";
      }
      ------------------------------------------------------------------------------------------------------
   2)基于区间的for循环 for (auto& d : doubleVector) 
      {
       d /= max;
       cout << d << " ";
      }
      ------------------------------------------------------------------------------------------------------
   3)访问对象元素中的字段 vector<string> stringVector(10, "hello");
      for (auto it = stringVector.begin(); it != stringVector.end(); ++it) 
      {
       it->append(" there");
      }
      // 或
      vector<string> stringVector(10, "hello");
      for (auto& str : stringVector) 
      {
       str.append(" there");
      }
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (8)迭代器:const_iterator  注:不能通过const_iterator修改元素
   cbegin()、cend() vector<string> stringVector(10, "hello");
      for (auto iter = stringVector.cbegin();
       iter != stringVector.cend(); ++iter) 
      {
       cout << *iter << endl;
      }
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (9)添加和删除元素
   push_back()、pop_back() 追加、删除
   insert()  (5种形式)从任意位置插入元素
       insert(const_iterator pos, const T& x); //将值x插入位置pos
       insert(const_iterator pos, size_type n, const T& x); //将值x在位置pos插入n次
       insert(const_iterator pos, InputIterator first, InputIterator last); //将范围first,last内的元素插入位置pos
   erase()   (2种形式)从任意位置删除元素
   clear()   删除所有元素
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (10)大小和容量
   size()   返回元素的个数
   capacity()  返回在重分配之前可以保存的元素个数。因此在重分配之前还能插入的元素个数为 capacity()-size()
   empty()   查询是否为空
   reserve()  分配保存指定数目元素的足够空间(不会创建真正的元素,因此不要越过vector大小访问元素)
   resize()  指定vector要保存的元素数目
 ----------------------------------------------------------------------------------------------------------------------------------------------
 (11)vector<bool>特化
   flip()   取反
      注:除非真的需要使用动态大小的位字段,否则应该避免使用vector<bool>,而是使用bitset
------------------------------------------------------------------------------------------------------------------------------------------------------
3、顺序容器(二):list
 (1)描述: 双向链表  不提供operator[]的随机访问操作,只有通过迭代器才能访问单个元素
 (2)访问元素 front()   返回list的第一个元素的引用
   back()   返回list的最后一个元素的引用
   begin()   返回第一个元素的迭代器
   end()   返回最后一个元素之后一个元素的迭代器
 (3)迭代器    不能进行加减操作和其他指针运算:可以通过++iter或--iter的方式遍历,而不能使用 iter+n或iter-n等
 (4)添加和删除 push_front  在首端追加
   pop_front  在首端移除
      注:list支持和vector一样的添加和删除元素的方法
          list适用于在数据结构上执行很多插入和删除操作,但不需要基于索引快睡访问元素的应用程序
 (5)大小和容量    注:支持size()、empty()、resize()
          不支持reserve()、capacity()
 (6)特殊list操作
   splice()  插入
   remove()、remove_if() 从list中删除特定元素
   unique()  从list删除连续重复元素
   merge()   合并灵感list
   sort()   对list中的元素执行稳定排序操作
   reverse()  翻转list中元素的顺序
------------------------------------------------------------------------------------------------------------------------------------------------------
4、顺序容器(三)
 (1)deque   双头序列 几乎和vector是等同的,使用得少。不要求元素连续保存在内存中
 (2)array(C++11)  数组  和vector类似,区别在于大小固定的,这个类的目的是让array能分配在栈上,而不是像vector总是需要访问堆
 (3)forward_list(C++11) 单链表  和list类似,区别在于只支持前向迭代 
------------------------------------------------------------------------------------------------------------------------------------------------------
5、容器适配器
 (1)queue   队列  template <class T, class Container = deque<T> > class queue;
 (2)priority_queue  优先级队列 template <class T, class Container = vector<T>,class Compare = less<T> >;
 (3)stack   栈  template <class T, class Container = deque<T> > class stack; 
------------------------------------------------------------------------------------------------------------------------------------------------------
5、关联容器(一)
 (1)pair工具类   <utility> template <class T1, class T2> struct pair;
       注:将两个可能属于不同类型的值组合起来,通过first和second公共数据成员访问这两个值
       pair<string, int> myPair("hello", 5);
       myOtherPair.first = "hello";
       myOtherPair.second = 6;
------------------------------------------------------------------------------------------------------------------------------------------------------
6、关联容器(二):map
 (1)插入元素   1)insert() 
     2)operator[]
 (2)访问元素   1)operator[]
     2)find()
     3)count() 查找是否存在具有给定键的元素
 (3)删除元素   1)erace()
------------------------------------------------------------------------------------------------------------------------------------------------------
7、关联容器(三):set
------------------------------------------------------------------------------------------------------------------------------------------------------
8、(C++11)无序关联容器/哈希表/散列表
------------------------------------------------------------------------------------------------------------------------------------------------------
9、其他容器:bitset
------------------------------------------------------------------------------------------------------------------------------------------------------
(done)
posted @ 2015-06-09 23:46  小精灵儿Pawn  Views(364)  Comments(0Edit  收藏  举报

如果您觉得此文有帮助,可以打赏点钱给我支付宝。 谢谢 -):