• 理解容器和迭代器


    第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)
  • 相关阅读:
    安装VMware Workstation提示the msi failed的解决办法
    windows2008中没有右键个性化
    delphi调用AdoQuery实现SqlSever的存储过程(返回)
    delphi 如何解决假死
    用A4打印总账,预览及打印无表头。。
    解决VMWare“Could not get vmci driver version句柄无效”的错误
    第一章 认识jQuery
    jQuery $.each用法
    jquery ui tabs详解(中文)
    javascript面向对象
  • 原文地址:https://www.cnblogs.com/likeFlyingFish/p/5346014.html
Copyright © 2020-2023  润新知