zoukankan      html  css  js  c++  java
  • 理解容器和迭代器

    第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)
  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/likeFlyingFish/p/5346014.html
Copyright © 2011-2022 走看看