【C++ Primer 学习笔记】: 容器和算法之【顺序容器】

原创 2015年11月17日 15:59:30

本系列博客主要是在学习 C++ Primer 时的一些总结和笔记。
【C++ Primer 学习笔记】: 容器和算法之【顺序容器】
本文地址:http://blog.csdn.net/shanglianlm/article/details/49888699

顺序容器

这里写图片描述

1 定义

头文件

#include <vector>
#include <list>
#include <deque>

1-1 初始化

这里写图片描述

接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持这种初始化。

1-2 容器内元素的类型约束

C++ 语言中,大多数类型都可用作容器的元素类型。容器元素类型必须满足以下两个约束:
• 元素类型必须支持赋值运算。
• 元素类型的对象必须可以复制。

引用不支持一般意义的赋值运算,因此没有元素是引用类型的容器。

除输入输出(IO)标准库类型之外,所有其他标准库类型都是有效的容器元素类型。

容器的容

// note spacing: use ">>" not ">>" when specifying a container element type 
vector< vector<string> > lines; // vector of vectors

2 迭代器和迭代器范围

2-1 迭代器操作

这里写图片描述

vector 和 deque 容器的迭代器提供额外的运算

这里写图片描述

2-2 迭代器范围

左闭合区间
这里写图片描述
这里写图片描述

3 顺序容器的操作

3-1 容器定义的类型别名

这里写图片描述

3-2 begin 和 end 成员

这里写图片描述

3-3 顺序容器中添加元素

这里写图片描述

避免存储 end 操作返回的迭代器
不要存储 end 操作返回的迭代器。添加或删除 deque 或 vector 容器内的元素都会导致存储的迭代器失效。

导致死循环的错误示例

例如,考虑一个读取容器中每个元素的循环,对读出元素做完处理后,在原始元素后面插入一个新元素。

vector<int>::iterator first = v.begin(), last = v.end(); // cache end iterator 
     // diaster: behavior of this loop is undefined 
while (first != last) { 
       // do some processing 
       // insert new value and reassign first, which otherwise would be invalid 
      first = v.insert(first, 42); 
      ++first; // advance first just past the element we added 
} 

为了避免存储 end 迭代器,可以在每次做完插入运算后重新计算 end 迭代器值:

// safer: recalculate end on each trip whenever the loop adds/erases elements 
while (first != v.end()) { 
   // do some processing 
   first = v.insert(first, 42); // insert new value 
   ++first; // advance first just past the element we added 
} 

3-4 关系操作符

C++ 语言只允许两个容器做其元素类型定义的关系运算。
所有容器都通过比较其元素对来实现关系运算: ivec1 < ivec2

假设 ivec1 和 ivec2 都是 vector 类型的容器,则上述比较使用了内置 int 型定义的小于操作符。如果这两个 vector 容器存储的是 strings 对象,则使用 string 类型的小于操作符。

如果上述 vector 容器存储 Sales_item 类型的对象,则该比较运算不合法。因为 Sales_item 类型没有定义关系运算,所以不能比较存放 Sales_items 对象的容器:

3-5 容器大小的操作

这里写图片描述

3-6 访问元素

这里写图片描述

// check that there are elements before dereferencing an iterator or calling front or back 
if (!ilist.empty()) { 
    // val and val2 refer to the same element 
   list<int>::reference val = *ilist.begin(); 
   list<int>::reference val2 = ilist.front(); 
   // last and last2 refer to the same element 
   list<int>::reference last = *--ilist.end(); 
   list<int>::reference last2 = ilist.back(); 
} 

3-7 删除元素

这里写图片描述

3-8 赋值与 swap

这里写图片描述

赋值和 assign 操作使左操作数容器的所有迭代器失效。swap 操作则不会使迭代器失效。完成 swap 操作后,尽管被交换的元素已经存放在另一容器中,但迭代器仍然指向相同的元素。

由于 assign 操作首先删除容器中原来存储的所有元素,因此,传递给 assign 函数的迭代器不能指向调用该函数的容器内的元素。

带有一对迭代器参数的 assign 操作允许我们将一个容器的元素赋给另一个不同类型的容器。

关于 swap 的一个重要问题在于:该操作不会删除或插入任何
元素,而且保证在常量时间内实现交换。由于容器内没有移动
任何元素,因此迭代器不会失效。

4 vector容器的自增长

4-1 capacity 和 reserve 成员

vector 类提供了两个成员函数:capacity 和 reserve 使程序员可与 vector 容器内存分配的实现部分交互工作。capacity 操作获取在容器需要分配更多的存储空间之前能够存储的元素总数,而 reserve 操作则告诉 vector 容器应该预留多少个元素的存储空间。

size 和 capacity 的区别:
size 指容器当前拥有的元素个数;
capacity 则指容器在必须分配新存储空间之前可以存储的元素总数。

5 容器的选用

通常来说,除非找到选择使用其他容器的更好理由,否则 vector 容器都是最佳选择。

这里写图片描述

6 容器适配器

这里写图片描述

头文件

#include <stack>
#include <queue>

默认的 stack 和 queue 都基于 deque 容器实现,而 priority_queue 则在 vector 容器上实现。在创建适配器时,通过将一个顺序容器指定为适配器的第二个类型实参,可覆盖其关联的基础容器类型:

// empty stack implemented on top of vector 
stack< string, vector<string> > str_stk; 
// str_stk2 is implemented on top of vector and holds a copy of svec 
stack<string, vector<string> > str_stk2(svec);

对于给定的适配器,其关联的容器必须满足一定的约束条件。stack 适配器所关联的基础容器可以是任意一种顺序容器类型。
因此,stack 栈可以建立在 vector、list 或者 deque 容器之上。
而 queue 适配器要求其关联的基础容器必须提供 push_front 运算,因此只能建立在 list 容器上,而不能建立在 vector 容器上。
priority_queue 适配器要求提供随机访问功能,因此可建立在 vector 或 deque 容器上,但不能建立在 list 容器上。

6-1 栈适配器

这里写图片描述

实例

// number of elements we'll put in our stack 
const stack<int>::size_type stk_size = 10; 
stack<int> intStack; // empty stack 
// fill up the stack 
int ix = 0; 
while (intStack.size() != stk_size) 
  // use postfix increment; want to push old value onto intStack 
  intStack.push(ix++); // intStack holds 0...9 inclusive
int error_cnt = 0; 
// look at each value and pop it off the stack 
while (intStack.empty() == false) { 
  int value = intStack.top(); 
  // read the top element of the stack 
  if (value != --ix) { 
         cerr << "oops! expected " << ix 
         << " received " << value << endl; 
         ++error_cnt; 
         } 
 intStack.pop(); // pop the top element, and repeat 
} 
cout << "Our program ran with " 
<< error_cnt << " errors!" << endl; 

声明语句:

stack<int> intStack; // empty stack 

6-2 队列和优先级队列

这里写图片描述

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 举报

相关文章推荐

C++Primer学习笔记(9)顺序容器

(1)顺序容器将单一类型元素聚集起来成为容器,然后根据位置来存储和访问。 (2)标准库提供了vector,list,deque三种顺序容器以及stack,queue, priority_queue三种...

C++ Primer 第9章 顺序容器 第一次学习笔记

好好学习天天向上。 C++ Primer第9章 顺序容器 的学习笔记

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

C++ Primer 学习笔记_29_STL实践与分析(3) --顺序容器的操作(下)

 STL实践与分析 --顺序容器的操作(下) 六、访问元素     如果容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用。 【与begi...

c++primer学习笔记 ( 第九章 顺序容器)

9.1顺序容器的定义 #include #include #include vector ivec;   //定义一个空的vector类型, vector ivec2(ivec);  /...

顺序容器 - 1【C++ Primer 学习笔记 - 第九章】

顺序容器: vector :  支持快速随机访问 list      :  支持快速插入/ 删除 deque:  双端队列    double-ended queue 顺序容器适配器 s...

顺序容器 - 2【C++ Primer 学习笔记 - 第九章】

list ilist(10); // 空容器:*ilist.begin() 无法解引用 // 空容器:back()、front() 操作,未定义 if(!ilist.empty()) { list:...

C++ primer第二次阅读学习笔记(第9章: 顺序容器)

第九章 顺序容器 顺序容器内的元素按位置进行存储和访问。元素的排列次序与元素值无关,而是由元素添加到容器的次序决定的。 标准库定义了三种顺序容器类型:vector,list,deque。它们的差别...

C++ Primer学习笔记:STL顺序容器

熊金水 2011-05-14 1、三种顺序容器的特点: Vector:在内存中顺序存储,支持快速随机访问,类似于C里的数组。可以高效的在vector尾部添加删除元素,但是,在vecto...

【C++ Primer 学习笔记】chapter9 顺序容器

顺序容器类型 1. 顺序容器 vector 支持快速随机访问 list 支持快速插入/删除 deque 双端队列 2. 顺序容器适配器 stack 后进先出(LIFO)栈 queue 先...
  • gxuan
  • gxuan
  • 2012-09-07 20:38
  • 515

C++ Primer 学习笔记_28_STL实践与分析(2) --顺序容器的操作(上)

 STL实践与分析 --顺序容器的操作(上) 引: 每种顺序容器都提供了一组有用的类型定义以及以下操作:     1)在容器内添加元素;     2)在容器中删除元素; ...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)