IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ primer 第九章 顺序容器 -> 正文阅读

[C++知识库]C++ primer 第九章 顺序容器

目录

9.1 顺序容器概述

9.2 容器库概览

9.2.1 迭代器

9.2.2 容器定义和初始化

9.2.3 赋值和swap

9.3 顺序容器操作

9.3.1 向顺序容器添加元素

9.3.2 访问元素

9.3.3 删除元素

9.3.4 特殊的forwa_list(单向链表)操作

9.3.5 改变容器大小????????

9.4 vector对象是如何增长的


定义:一个容器就是一个特定类型对象的集合。

9.1 顺序容器概述

(1)顺序容器类型

? ? ? ? vector:可变数组大小,支持快速访问

? ? ? ? deque:双端队列,支持快速随机访问,在头尾位置插入/删除速度很快

? ? ? ? forward_list:单向链表,只支持单向顺序访问。

? ? ? ? array:固定大小数组,不能添加或删除元素

? ? ? ? string:和vector类似,用来保存字符

9.2 容器库概览

9.2.1 迭代器

? ? ? ? 迭代器范围由一对迭代器表示,,通常被称为begin和end,而end从来都不会指向范围中的最后一个元素,而是指向尾元素之后的位置,其元素范围由数学表示为:

? ? ? ? [begin,end)

9.2.2 容器定义和初始化

? ? ? ? (1)将一个容器初始化为另一个容器的拷贝

? ? ? ? ? ? ? ? 可拷贝整个容器,也可以拷贝一个指定容器的元素范围

? ? ? ? ? ? ? ? 新容器和原容器的元素类型可以不同,只要能将要拷贝的元素转换为要初始化的元素的类型即可

list<string> authors={"nuktib","sha"m"aus"}
vector<const char *> articles={"a","an","the"}

list<string> list2(authors);      //正确,类型匹配
deque<string> authList(authors)   //错误,容器类型不匹配
forward_list<string> words(articles.begin(),articles.end())
//上述正确,可以将const char*元素转换为string

? ? ? ? (2)与顺序容器大小相关的构造函数

? ? ? ? ? ? ? ? 其中一个构造函数接收一个容器大小和一个元素初始值

list<string> i(10,"hi")   //10个strings元素,每个都初始化为"hi"
vector<int> v(10,-1)     //10个int元素,每个都初始化为-1
deque<string> i(10)     //10个元素,每个都是空的string

? ? ? ? (3)标准库array具有固定大小

? ? ? ? ? ? ? ?定义一个array时,除了指定元素类型,还要指定容器大小

array<int,42>
array<string,10>

? ? ? ? ? ? ? 内置数组不支持拷贝或对象赋值操作,但array无此限制

int digs[10]={1,2,3}
int cpy[10]=digs   //错误,内置数组不支持拷贝和赋值

array<int,10> d={1,2,3,4,5,6,7}
array<int,10> c=d   //正确

9.2.3 赋值和swap

? ? ? ?(1) assign赋值函数(仅顺序容器)

? ? ? ? 顺序容器定义了一个名为assign的成员,允许我们从一个不同但相容的类型赋值,或者从一个容器的子序列赋值。

? ? ? ? 例:?

list<string> name;
vector<const char*>old;
name.assign(old.cbegin(),old.cend())

? ? ? ? 上述代码将name中的元素替换为迭代器指定范围中的元素的拷贝,assign的参数决定了容器中将有多少个元素以及他们的值是什么

? ? ? ? (2)使用swap

? ? ? ? swap操作交换两个相同类型容器的内容

vector<string> v1(10);
vector<string> v2(20);
上述交换结束后,v1将会拥有20个元素,v2将会拥有10个元素

9.3 顺序容器操作

9.3.1 向顺序容器添加元素

(1)使用push_back

? ? ? ? 除了array和forward_list之外,每个顺序容器都支持push_back

?(2)push_front

? ? ? ? list,forward_list,deque容器还支持push_front将元素插入容器头部

list<int> l;
for(int i=0;i!=4;i++)
    l.push_front(i)

(3)在特定位置添加元素

? ? ? ? insert函数可在特定位置添加元素,每个insert元素都接受一个迭代器作为其第一个参数,insert函数将元素插入到迭代器所指得位置之前

? ? ? ?虽然有些容器不支持push_front操作,但他们对于insert操作无此限制,因此可以将元素插入到容器开始的位置,不必担心容器是否支持push_front

? ? ? ? insert另一个版本还接受一个元素数目和一个值,将指定数目的元素添加到指定位置之前。

? ? ? ? s.insert(s.end(),10,"anna")? //将10个元素插入到s的末尾

? ? ? ? 还可以接受一对迭代器或一个初始化列表插入

s.insert(s.end(),{"thses","as","sda","dasda"});

????????

? ? ? ? 使用insert的返回值

list<string> l;
auto iter = l.begin();
string word;
while (cin >> word)
	iter = l.insert(iter, word);

? ? ? ?上述代码实现在一个特定位置反复插入元素

????????第一次调用insert将刚刚读取的string插入到iter所指向的元素之前,insert返回的迭代器恰好指向这个新元素,我们将此迭代器赋予iter并重新开始循环,读取下一个单词,不断循环。

9.3.2 访问元素

? ? ? ? 所有顺序容器都存在一个front成员函数,,除了forward_list之外的所有顺序容器都由一个back成员函数,front成员函数返回首元素的引用,back成员函数返回尾元素的引用

? ? ? ? 可以通过该引用修改容器中元素的值

if(!c.empty())
{
    c.front()=42;
    auto &v=c.back()
    v=1024;
}

9.3.3 删除元素

? ? ? ? (1)pop_front和pop_back成员函数分别删除首元素和尾元素,vector和string,forward_list不支持上述操作

? ? ? ? (2)earse

? ? ? ? ? ? ? ?成员函数erase从容器指定位置删除元素,也可以删除迭代器指定的单个元素,也可以删除由一对迭代器指定的范围内的所有元素,上述最终均会返回指向删除的元素之后位置的迭代器。

? ? ? ? 例:删除所有的奇数

list<int> ls = { 0,1,2,3,4,5,6,7,8,9 };
auto it = ls.begin();
while (it != ls.end())
{
	if (*it % 2)
		it = ls.erase(it);
	else
		it++;
}

????????

? ? ? ? 接受一堆迭代器的erase版本允许我们删除一个范围内的元素:

? ? ? ? 例: s.erase(s.begin(),s.end())

9.3.4 特殊的forwa_list(单向链表)操作

? ? ? ? 单向链表中由于特殊的插入和删除,所以定义的函数也比较特殊

? ? ? ? before_begin():返回指向链表首元素之前不存在的元素的迭代器,此迭代器不能解引用

? ? ? ? insert_after(p,t):在迭代器p之后插入元素t

? ? ? ? erase_after(p):删除p所指位置之后的元素

? ? ? 例:删除奇数元素:

forward_list<int> lst = { 0,1,2,3,4,5,6,7,8,9 };
auto pre = lst.before_begin();
auto cur = lst.begin();
while (cur != lst.end())
{
	if (*cur % 2)
		cur = lst.erase_after(pre);   //将cur重置为erase_after的返回值,即指向cur的下一个元素
	else
	{
		pre = cur;
		cur++;
	}
}

9.3.5 改变容器大小?

? ? ? ? 通过resize函数可以改变容器的大小,但array不支持此操作

? ? ? ? c.resize(n):调整c为n个元素????????

? ? ? ? c.resize(n,t):调整c为n个元素,任何新添加的元素都初始化为t

9.4 vector对象是如何增长的

? ? ? ? 为了支持随机访问,vector将元素连续存储,当不得不获取新的内存控件时,vector和string通常会分配比新的控件需求更大的内存控件,容器预留这些空间作为备用,可以保存更多元素。

? ? ? ? capacity函数告诉我们容器在不扩张内存空间情况下可以容纳多少元素

? ? ? ? size():是指目前已经保存的元素的数目

? ? ? ? reverse(n):告诉容器至少分配容纳n给元素的空间

????????

????????

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 18:48:02  更:2022-06-29 18:50:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/19 19:29:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码