STL标准模板库3(顺序容器)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
NEW
NEW
容器的选择3-2
2.元素的访问如何影来自百度文库容器的选择
– 通常来说,除非找到使用其他容器的更好理由,否则vector容器都 是最佳选择
容器的选择3-3
2.选择容器提示 如果程序要求随机访问元素,则应使用vector或者deque 如果程序必须在容器中间插入或者删除元素,则因使用 list 如果程序不是在容器的中间位置,而是在容器的首部或者 尾部插入或者删除数据,则应采用deque
STL
顺序容器
本章内容
顺序容器的定义 迭代器和迭代器范围 顺序容器操作 vector容器自增长 容器的选择 再谈string类型 容器适配器
顺序容器类型
将单一类型元素聚集起来成为容器,任何根据位置来存储和访问这些元素,这就是顺序容器 顺序容器的元素排列次序和元素值没有关系,而是由元素添加到容器中的次序决定
删除迭代器b和e所标记范围内的所有元素 删除容器C内的所有元素 删除容器C的最后一个元素,如果为空,则函数未定义 删除容器C的第一个元素,如果为空,则函数未定义
c.erase(b, e) c.clear() c.pop_back()仅list,deque c.pop_pront()仅list,deque
End
Begin
迭代器的范围
一大堆练习
要标记出有效的迭代器范围迭代器需要满足什么约束?
– – 他们指向同一个同期的元素,或者超过末端的下一个位置 如果两个迭代器不相等,则对first反复自加必须能够到达last,也就是last不能在first之前。
编写一个函数,其形参是一对迭代器和一个int型数值,实现在 迭代器标记的范围内寻找该int型数值的功能,并返回一个bool 结果,以指明是否找到。 重写程序,返回指向找到的元素的迭代器,确保元素不存在的 情况下也能工作。 使用迭代器编写程序,从标准输入设备读入若干string对象, 并将它们存储在一个vector对象中,输出vector对象所有元素 。 用list重写上题得到的程序,列出改变了容器类型后要做的修 改。
– – – – – – – – – – – –
ivce1:1 3 5 7 9 12 ivce2:0 2 3 6 8 10 12 ivce3:1 3 9 ivce4:1 3 5 7 ivce5:1 3 5 7 9 12 ivce1 < ivce2 ivce2 < ivce1 ivce1 < ivce3 ivce1 < ivce4 ivce1 == ivce5 ivce1 == ivce4 ivce1 != ivce4
capacity和reserve
capacity(容量)和size(长度):
– size是指容器当前拥有的元素个数 – capacity则是指容器必须分配新存储空间之前可以存储的元素总数
1
2
3
4
·· 23 ·
额外的空间
ivec1.size()
ivec1.capacity()
容器的选用3-1
1.插入操作如何影响容器的选择
赋值与swap
赋值操作首先删除其左操作容器中的所有元素,然后将右 操作符插入到左边容器中:
顺序容器的复制操作 c1 = c2 先删除容器c1的所有元素,然后将c2的元素复制给c1,c1c2 类型必须相同 交换内容: 重新设置C的元素,将迭代器b和e标记范围内的元素复制到C 中,be必须不是指向c中元素的迭代器
c1.swap(c2) c.assign(b,e)
c.aasign(n, t)
将容器c重新设置为存储n个值为t的元素
容器的自增长
NEW
1, 重新分配内存空间,用于存放原来的元素以及新添加的 元素 2,存放在旧存储空间的元素被赋值到新存储的空间里 3,插入新元素 4,撤销旧的存储空间
对于不连续的存储元素容器,不存在这样的内存分配问题
练习
需要删除一段元素时候,如果val1和val2相等,那么程序会发 生什么情况?如果其中有一个不存在,或者两个都不存在,会 怎样? 假设有如下ia的定义:int ia[] = {0,1,1,2,3,5,8,13,21,55,89};将ia赋值到一个vector和一个 list容器中,使用单个迭代器参数版本的erase函数将list容器 中的奇数值元素删除掉,然后将vector容器中的偶数值元素删 除掉。 编写一个程序处理一个string类型的list容器,在改容器中寻 找一个特殊值,如果找到,将它删除。用deque重写上述函数。
常量迭代器
另一种防止数据被改变得方法是将容器申明为const类型。
3.3 迭代器和迭代器范围
常用迭代器运算 *iter Iter->mem ++iter iter++ --iter iter-iter1 == iter2 比较两个迭代器是否相等或者不等。当两个迭代器指向同一个容 器中的同一个元素,或者当他们都指向同一个容器的超出末端的 下一位置时,迭代器相等 给iter减1,使其指向容器中的上一个元素 返回迭代器iter所指向的元素的引用
指针迭代器
一个指针也是一种迭代器。备注中程序同样显示了STL的一 个主要特性——它不只是能够用于它自己的类类型,而且 也能用于任何C或C++类型
容器迭代器
尽管C++指针也是迭代器,但用的更多的是容器迭代器。容 器迭代器用法和上页程序一样,但和将迭代器申明为指针 变量不同的是,你可以使用容器类方法来获取迭代器对象 。两个典型的容器类方法是begin()和end()。它们在大多 数容器中表示整个容器范围。其他一些容器还使用 rbegin()和rend()方法提供反向迭代器,以按反向顺序指 定对象范围。
下列比较的结果:
思考
编写程序判断一个vector<int>容器所包含的元素是否与一 个list<int>所包含的元素相同。
假设C1和C2都是容器,下列用法给C1和C2的元素类型带来 什么约束? – if(c1 <c2) – (如果有的话)对C1和C2的约束又是什么?
容器大小的操作
顺序容器的大小操作 c.size() c.max_size() c.empty() 返回容器C的元素个数,返回类型为size_type 返回容器可容纳的最多元素个数 返回容器大小是否为0
如果只需要在读取输入的时候在容器中间插入元素,然后 需要随机访问,该怎么办? 如果既要随机访问又必须在容器中插入或者删除元素,应 该怎么办?
修改记录
• •
2010-12-12 根据adrian版修改建立 彭君 2011-01-11 调整部分代码 彭君
在容器C的尾部添加职位t的元素,返回void 在容器C的前端添加值为t的元素,返回void
以下只适用 list 和 deque 在迭代器p所指的元素前面插入值为t的新元素,返回指向新添 加的元素的迭代器 在迭代器p所指的元素前面添加n个为t的新元素值,返回void 在迭代器p所指元素的前面插入由迭代器b和e标记的范围内的元 素,返回void
对iter进行解引用,获取执行元素中名为mem的成员,等效于(*iter).mem
给iter加1,使其指向容器中的下一个元素
iter1 != iter2
vector和deque特殊迭代器运算
vector和deque的迭代器支持的操作
iter + n
在迭代器上加(减)整数值n,将产生指向容器前面(后面)第 n个元素的迭代器。新计算出来的迭代器必须指向容器中的元 素或者超出容器末端的下一个位置。
迭代器失效的问题
移动或者删除元素后,会是被移动元素的迭代器失效,也 可能同时让其他迭代器失效。
E n Begin d
Begin
End
3.3 顺序容器的操作
在容器中添加元素 在容器中删除元素 设置容器的大小 (如果有的话)获取容器的第一个和最后一个元素
容器定义的类型别名
容器定义的类型别名
size_type iterator
同上 两个迭代器减法,其运算结果是
iter - n iter1 - iter2 > , >= < , <=
思考
迭代器的范围
迭代器范围的概念是标准库的基础 [first, last)左闭合区间概念 左闭合的意义:
– – – – 当first和last相等时,迭代器范围为空 当first和last不相等时,迭代器范围至少有一个元素。 以上两条意味着代码可以这样写: while(first != last ){++first;}
练习
编程程序将int行的list容器的所有元素复制到两个deque 容器中,list容器的元素如果为偶数,则复试到一个deque 容器中,如果为奇数,就复制到另一个deque容器中。 假设iv是一个int型vector容器,下列程序有什么错误?
容器比较:关系操作符
C++只允许两个容器做其元素类型定义的关系运算 例子:
顺序容器 vector list 支持快速随机访问 支持快速插入/删除
deque
双端队列
顺序容器适配器 stack queue 栈 队列
priority_queue
有优先级管理的队列
顺序容器的定义
思考
1
2 创建和初始化一个vector对象有4种方法,为每一种方式 提供一个例子,并解释每个例子生成的vector对象包含什 么值。 3 解释复制容器对象的构造函数和使用两个迭代器的构造 函数之间的差别。
容器内元素的约束
元素类型必须支持赋值运算 元素类型的对象必须可以复制
注意:输入输出(IO)标准库类型不支持复制或赋值所以不能创建存放IO类型对象的容器。
容器的容器
/*容器的容器*/ vector< vector<string>> lines;
思考
1 定义一个list对象类存储deque对象,该对象存放int类 型元素。 2 为什么我们不能使用容器类存iostream对象? 3 假设有一个名为Foo的类,这个类没有定义默认构造函数 ,但是提供了一个需要一个int型参数的构造函数,定义一 个存放Foo的list对象,该list对象有10个元素。
c.resize(n)
c.resize(n,t)
调整容器长度大小,使其能容纳n个元素,如果n<size,则删除多出 的 元素,否则添加采用初始值的新元素
调整容器长度大小,使其能容纳n个元素,所有新添元素的值都为t
访问容器元素
删除元素
c.erase(p)
删除迭代器所指向的元素,返回一个迭代器,指向被删除 元素的后面的元素。如果P指向容器内的最后一个元素, 则返回指向容器超出末端的下一个位置。如果P本身就是 指向超出末端的下一个位置,则该函数未定义
const_iterator value_type reverse_iterator ... ...
无符号整数,足以存放此容器的最大可能容器长度 容器类型的迭代器类型
元素的只读迭代器类型 元素类型 按逆序寻址元素的迭代器
向容器中添加元素
c.push_back c.push_front
c.insert(p, t) c.insert(p, n, t) c.insert(p, b, e)
NEW
容器的选择3-2
2.元素的访问如何影来自百度文库容器的选择
– 通常来说,除非找到使用其他容器的更好理由,否则vector容器都 是最佳选择
容器的选择3-3
2.选择容器提示 如果程序要求随机访问元素,则应使用vector或者deque 如果程序必须在容器中间插入或者删除元素,则因使用 list 如果程序不是在容器的中间位置,而是在容器的首部或者 尾部插入或者删除数据,则应采用deque
STL
顺序容器
本章内容
顺序容器的定义 迭代器和迭代器范围 顺序容器操作 vector容器自增长 容器的选择 再谈string类型 容器适配器
顺序容器类型
将单一类型元素聚集起来成为容器,任何根据位置来存储和访问这些元素,这就是顺序容器 顺序容器的元素排列次序和元素值没有关系,而是由元素添加到容器中的次序决定
删除迭代器b和e所标记范围内的所有元素 删除容器C内的所有元素 删除容器C的最后一个元素,如果为空,则函数未定义 删除容器C的第一个元素,如果为空,则函数未定义
c.erase(b, e) c.clear() c.pop_back()仅list,deque c.pop_pront()仅list,deque
End
Begin
迭代器的范围
一大堆练习
要标记出有效的迭代器范围迭代器需要满足什么约束?
– – 他们指向同一个同期的元素,或者超过末端的下一个位置 如果两个迭代器不相等,则对first反复自加必须能够到达last,也就是last不能在first之前。
编写一个函数,其形参是一对迭代器和一个int型数值,实现在 迭代器标记的范围内寻找该int型数值的功能,并返回一个bool 结果,以指明是否找到。 重写程序,返回指向找到的元素的迭代器,确保元素不存在的 情况下也能工作。 使用迭代器编写程序,从标准输入设备读入若干string对象, 并将它们存储在一个vector对象中,输出vector对象所有元素 。 用list重写上题得到的程序,列出改变了容器类型后要做的修 改。
– – – – – – – – – – – –
ivce1:1 3 5 7 9 12 ivce2:0 2 3 6 8 10 12 ivce3:1 3 9 ivce4:1 3 5 7 ivce5:1 3 5 7 9 12 ivce1 < ivce2 ivce2 < ivce1 ivce1 < ivce3 ivce1 < ivce4 ivce1 == ivce5 ivce1 == ivce4 ivce1 != ivce4
capacity和reserve
capacity(容量)和size(长度):
– size是指容器当前拥有的元素个数 – capacity则是指容器必须分配新存储空间之前可以存储的元素总数
1
2
3
4
·· 23 ·
额外的空间
ivec1.size()
ivec1.capacity()
容器的选用3-1
1.插入操作如何影响容器的选择
赋值与swap
赋值操作首先删除其左操作容器中的所有元素,然后将右 操作符插入到左边容器中:
顺序容器的复制操作 c1 = c2 先删除容器c1的所有元素,然后将c2的元素复制给c1,c1c2 类型必须相同 交换内容: 重新设置C的元素,将迭代器b和e标记范围内的元素复制到C 中,be必须不是指向c中元素的迭代器
c1.swap(c2) c.assign(b,e)
c.aasign(n, t)
将容器c重新设置为存储n个值为t的元素
容器的自增长
NEW
1, 重新分配内存空间,用于存放原来的元素以及新添加的 元素 2,存放在旧存储空间的元素被赋值到新存储的空间里 3,插入新元素 4,撤销旧的存储空间
对于不连续的存储元素容器,不存在这样的内存分配问题
练习
需要删除一段元素时候,如果val1和val2相等,那么程序会发 生什么情况?如果其中有一个不存在,或者两个都不存在,会 怎样? 假设有如下ia的定义:int ia[] = {0,1,1,2,3,5,8,13,21,55,89};将ia赋值到一个vector和一个 list容器中,使用单个迭代器参数版本的erase函数将list容器 中的奇数值元素删除掉,然后将vector容器中的偶数值元素删 除掉。 编写一个程序处理一个string类型的list容器,在改容器中寻 找一个特殊值,如果找到,将它删除。用deque重写上述函数。
常量迭代器
另一种防止数据被改变得方法是将容器申明为const类型。
3.3 迭代器和迭代器范围
常用迭代器运算 *iter Iter->mem ++iter iter++ --iter iter-iter1 == iter2 比较两个迭代器是否相等或者不等。当两个迭代器指向同一个容 器中的同一个元素,或者当他们都指向同一个容器的超出末端的 下一位置时,迭代器相等 给iter减1,使其指向容器中的上一个元素 返回迭代器iter所指向的元素的引用
指针迭代器
一个指针也是一种迭代器。备注中程序同样显示了STL的一 个主要特性——它不只是能够用于它自己的类类型,而且 也能用于任何C或C++类型
容器迭代器
尽管C++指针也是迭代器,但用的更多的是容器迭代器。容 器迭代器用法和上页程序一样,但和将迭代器申明为指针 变量不同的是,你可以使用容器类方法来获取迭代器对象 。两个典型的容器类方法是begin()和end()。它们在大多 数容器中表示整个容器范围。其他一些容器还使用 rbegin()和rend()方法提供反向迭代器,以按反向顺序指 定对象范围。
下列比较的结果:
思考
编写程序判断一个vector<int>容器所包含的元素是否与一 个list<int>所包含的元素相同。
假设C1和C2都是容器,下列用法给C1和C2的元素类型带来 什么约束? – if(c1 <c2) – (如果有的话)对C1和C2的约束又是什么?
容器大小的操作
顺序容器的大小操作 c.size() c.max_size() c.empty() 返回容器C的元素个数,返回类型为size_type 返回容器可容纳的最多元素个数 返回容器大小是否为0
如果只需要在读取输入的时候在容器中间插入元素,然后 需要随机访问,该怎么办? 如果既要随机访问又必须在容器中插入或者删除元素,应 该怎么办?
修改记录
• •
2010-12-12 根据adrian版修改建立 彭君 2011-01-11 调整部分代码 彭君
在容器C的尾部添加职位t的元素,返回void 在容器C的前端添加值为t的元素,返回void
以下只适用 list 和 deque 在迭代器p所指的元素前面插入值为t的新元素,返回指向新添 加的元素的迭代器 在迭代器p所指的元素前面添加n个为t的新元素值,返回void 在迭代器p所指元素的前面插入由迭代器b和e标记的范围内的元 素,返回void
对iter进行解引用,获取执行元素中名为mem的成员,等效于(*iter).mem
给iter加1,使其指向容器中的下一个元素
iter1 != iter2
vector和deque特殊迭代器运算
vector和deque的迭代器支持的操作
iter + n
在迭代器上加(减)整数值n,将产生指向容器前面(后面)第 n个元素的迭代器。新计算出来的迭代器必须指向容器中的元 素或者超出容器末端的下一个位置。
迭代器失效的问题
移动或者删除元素后,会是被移动元素的迭代器失效,也 可能同时让其他迭代器失效。
E n Begin d
Begin
End
3.3 顺序容器的操作
在容器中添加元素 在容器中删除元素 设置容器的大小 (如果有的话)获取容器的第一个和最后一个元素
容器定义的类型别名
容器定义的类型别名
size_type iterator
同上 两个迭代器减法,其运算结果是
iter - n iter1 - iter2 > , >= < , <=
思考
迭代器的范围
迭代器范围的概念是标准库的基础 [first, last)左闭合区间概念 左闭合的意义:
– – – – 当first和last相等时,迭代器范围为空 当first和last不相等时,迭代器范围至少有一个元素。 以上两条意味着代码可以这样写: while(first != last ){++first;}
练习
编程程序将int行的list容器的所有元素复制到两个deque 容器中,list容器的元素如果为偶数,则复试到一个deque 容器中,如果为奇数,就复制到另一个deque容器中。 假设iv是一个int型vector容器,下列程序有什么错误?
容器比较:关系操作符
C++只允许两个容器做其元素类型定义的关系运算 例子:
顺序容器 vector list 支持快速随机访问 支持快速插入/删除
deque
双端队列
顺序容器适配器 stack queue 栈 队列
priority_queue
有优先级管理的队列
顺序容器的定义
思考
1
2 创建和初始化一个vector对象有4种方法,为每一种方式 提供一个例子,并解释每个例子生成的vector对象包含什 么值。 3 解释复制容器对象的构造函数和使用两个迭代器的构造 函数之间的差别。
容器内元素的约束
元素类型必须支持赋值运算 元素类型的对象必须可以复制
注意:输入输出(IO)标准库类型不支持复制或赋值所以不能创建存放IO类型对象的容器。
容器的容器
/*容器的容器*/ vector< vector<string>> lines;
思考
1 定义一个list对象类存储deque对象,该对象存放int类 型元素。 2 为什么我们不能使用容器类存iostream对象? 3 假设有一个名为Foo的类,这个类没有定义默认构造函数 ,但是提供了一个需要一个int型参数的构造函数,定义一 个存放Foo的list对象,该list对象有10个元素。
c.resize(n)
c.resize(n,t)
调整容器长度大小,使其能容纳n个元素,如果n<size,则删除多出 的 元素,否则添加采用初始值的新元素
调整容器长度大小,使其能容纳n个元素,所有新添元素的值都为t
访问容器元素
删除元素
c.erase(p)
删除迭代器所指向的元素,返回一个迭代器,指向被删除 元素的后面的元素。如果P指向容器内的最后一个元素, 则返回指向容器超出末端的下一个位置。如果P本身就是 指向超出末端的下一个位置,则该函数未定义
const_iterator value_type reverse_iterator ... ...
无符号整数,足以存放此容器的最大可能容器长度 容器类型的迭代器类型
元素的只读迭代器类型 元素类型 按逆序寻址元素的迭代器
向容器中添加元素
c.push_back c.push_front
c.insert(p, t) c.insert(p, n, t) c.insert(p, b, e)