1. 顺序容器概述

#include <vector>  //可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢
#include <deque>  //双端队列。支持快速随机访问。在头尾位置插入、删除速度都很快
#include <list>       //双向链表。只支持双向顺序访问。在list中任何位置进行插入、删除操作速度都很快
#include <array>  //固定大小数组。 支持快速随机访问。不能添加或删除元素
#include <string> //与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入、删除速度快/*通常,使用vector是最好的选择,除非有很好的理由选择其他容器
可以定义一个容器,其元素的类型是另一个容器:vector<vector<string>> lines;
此处lines是一个vector,其元素类型是string的vector



2. 左闭合范围

一个迭代器范围由一对迭代器表示,两个迭代器分别指向同一个容器中的元素或尾元素之后的位置。

左闭合区间:[begin,end)表示范围自begin开始,于end之前结束(end不能指向begin之前的位置)

使用左闭合范围有三种方便的性质:

a) 如果begin==end,范围为空

b) 如果begin!=end,则范围至少包含一个元素

c) 可以对begin递增若干次,使begin==end

因此,我们可以用循环处理一个元素范围,给定合法范围的begin和end,若范围为空,则退出循环

3. vector和string迭代器支持>、>=、<、<=关系运算符,但list不支持

list<int> lst1;
list<int>::iterator iter1=lst1.begin(),iter2=lst1.end();
/*while(iter1<iter2) 这是不可以的诶*/
while(iter1!=iter2)    /*这才是对的*/ 

4. begin(返回指向第一个元素或第一个字符的迭代器)和end(返回指向容器或string对象尾元素的下一位置的迭代器)有多个坂(版)本:

a) rbegin和rend返回反向迭代器

b) 以c开头的坂本则返回const迭代器

list<string> a={"Milton","Shakespear","Austen"};
auto it1=a.begin();        //list<string>::iterator
auto it2=a.rbegin();   //list<string>::reverse_iterator
auto it3=a.cbegin();   //list<string>::const_iterator
auto it4=a.crbegin();  //list<string>::const_reverse_iterator

5. 迭代器类型

a) 当不需要写访问时,应使用cbegin和cend

b) 如果对象是个常量,只能使用const_iterator

        vector<int> v1;const vector<int> v2;auto it1=v1.begin(),it2=v2.begin();        //error,it1和it2类型不一致auto it3=v1.cbegin(),it4=v2.cbegin();


6. 容器定义和初始化

#include <iostream>
#include <vector>
using namespace std;
int main(){vector<int> v1;                //默认初始化。如果不是array, 容器为空vector<int> v2(v1);         //v2初始化为v1的拷贝。这两个容器必须是相同的容器类型,vector<int> v3=v1;          //且保存的是相同的元素类型 vector<int> v4{1,2,3};         //列表初始化,初始化为初始化列表中元素的拷贝, vector<int> v5={1,2,3};           //列表中元素的类型必须与容器的元素类型相同 vector<int> v6(v1.begin(),v1.end());   //初始化为两个迭代器指定范围中的元素的拷贝vector<int> v7(10,-1);          //10个int元素,每个都初始化为-1vector<int> v8(10);            //10个int元素,每个都初始化为0 return 0;
} 

注意:当传递迭代器参数来拷贝一个范围时,不要求容器类型是相同的,只要能将要拷贝的元素转换为要初始化的容器的元素类型即可:

        vector<float> ivec1={0.1,0.5,5.6};vector<int> ivec2(ivec1.begin(),ivec1.end());

7. swap:交换两个相同类型容器的内容。

元素本身并未交换,swap只是交换了两个容器的内部数据结构,which means除string外,指向容器的迭代器、引用和指针在swap操作之后都不会失效,它们仍指向

swap操作之前所指向的那些元素。

8. 容器大小操作

每个容器都有三个与大小相关的操作:

a) size返回容器中元素的数目

b) empty当size为0时返回布尔值true

c) max_size返回一个大于或等于该类型容器所能容纳的最大元素数的值

d) 每个容器类型都支持相等运算符(==和!=);除了无序关联容器外的所有容器都支持关系运算符(>、>=、<、<=)

e) 关系运算符左右两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素

9. 向顺序容器添加元素(vector和string不支持push_front和emplace_front)

c.push_back(t)               //在c的尾部创建一个值为t或由args创建的元素
c.emplace_back(args)            //返回voidc.insert(p,t)               //在迭代器p指向的元素之前创建一个值为r或由args创建的元素
c.emplace(p,args)           //返回voidc.insert(p,n,t)             //在迭代器p指向的元素之前插入n个值为t的元素。//返回指向新添加的第一个元素的迭代器;若n为0,则返回p c.insert(p,b,e)                //将迭代器p和e指定的范围内的元素插入到迭代器p指向的元素之前。b和e不能指向c中的元素。//返回指向新添加的第一个元素的迭代器;若范围为空,则返回p c.insert(p,il)               //il是一个花括号包围的元素值列表。将这些给定值插入到迭代器p指向的元素之前。//返回指向新添加的第一个元素的迭代器;若列表为空,则返回p

a) 向一个vector、string或deque插入元素会使所有指向容器的迭代器、引用和指针失效

b) 当用一个对象初始化容器时(或将一个对象插入到容器中时),实际上放到容器中的是对象值的一个拷贝而不是其本身;随后对容器中元素的任何改变都不会影响到原始对象

c) 每个insert函数都接受一个迭代器作为其第一个参数,将元素插入到迭代器所指定的位置之前

        vector<int> vec{1,10,24,3};vec.insert(vec.begin(),4);for(auto c:vec)cout<<c<<" ";
输出结果为4 1 10 24 3

d) insert还有一个版本接受的参数为一个元素数目和一个值,它将指定数量的元素添加到指定位置之前,这些值都按给定值初始化

        vector<string> svec{"hhh"};svec.insert(svec.end(),10,"A233");
输出结果为hhh A233 A233 A233

e) 接受一对迭代器或一个初始化列表的insert坂本将给定范围中的元素插入到指定位置之前

        vector<string> svec1={"i","love","study","and"};vector<string> svec2={"study","makes","me","happy"};svec2.insert(svec2.begin(),svec1.begin(),svec1.end()-2);     //将svec1最后的两个元素添加到svec2的开始位置for(auto c:svec2)cout<<c<<" ";svec1.insert(svec1.end(),{"i","want","to","be","a dalao"});for(auto n:svec1)cout<<n<<" ";

注意:拷贝的范围是左闭合区间,即第三行的svec1.end()-2,the string "study",没有被拷贝过去

f) 使用insert的返回值可以在容器中一个特定位置反复插入元素,因为insert函数返回的是新添加的(第一个元素的)迭代器

   vector<string> svec={"anita","Anita","ANITA","gcn","GCN"};auto iter=svec.begin();string word;while(cin>>word)iter=svec.insert(iter,word);      //等价于调用push_frontfor(auto c:svec)cout<<c<<" ";

10. 访问元素

a) 每个顺序容器都有一个front成员函数,除forward_list之外的所有顺序容器都有一个back成员函数。这两个操作分别返回首元素和尾元素的引用

  c.back()    //返回c中尾元素的引用,若c为空,函数行为未定义c.front()   //返回c中首元素的引用,若c为空,函数行为未定义c[n]        //返回c中下标为n的元素的引用,n是一个无符号整数,若n>=c.size(),函数行为未定义 c.at[n]       //返回下标为n的元素的引用。如果下标越界,则抛出一out_of_range异常 

b) 不可以对空容器调用front和back

c) 在容器中访问元素的成员函数(front、back、下标和at)返回的是引用。如果容器是一个const对象,返回值是const引用。如果容器不是const,可以用返回的普通引用改变元素的值

    vector<int> ivec={7,2,4,6,2,0,9};if(!ivec.empty()){      ivec.front()=42;           //将42赋予c中的第一个元素 auto &v1=ivec.back();          //获得指向最后一个元素的引用cv1=1024;auto v2=ivec.back();          //v2不是一个引用,只是ivec.back()的拷贝v2=0;                    //v2不是引用,未改变c中的元素 }for(auto a:ivec)cout<<a<<" ";               //输出结果是42 2 4 6 2 0 1024

11. 删除元素(与vector和string不支持push_front一样,vector和string也不支持pop_front)

c.pop_back()       //删除c中尾元素,返回void
c.pop_front()       //删除c中首元素,返回void
c.erase(p)      //删除迭代器p所指定的元素,返回一个指向被删元素之后元素的迭代器。若p指向尾元素,返回尾后迭代器。
c.erase(b,e)        //删除迭代器b和e所指定范围内的元素。返回一个指向最后一个被删的元素之后元素的迭代器
c.clear()       //删除c中所有元素,返回void 

a) pop_front和pop_back都返回void。如果需要弹出的元素的值,应在执行弹出操作之前保存它

b) 成员函数erase从容器中指定位置删除元素,两种形式的erase都返回指向删除的(最后一个)元素之后位置的迭代器。下面的栗子删除ivec中的所有奇数,调用了接受一个迭代器的erase坂本的函数

  vector<int> ivec;int n;while(cin>>n)ivec.push_back(n);auto it=ivec.begin();while(it!=ivec.end()){         //不为空if(*it%2)it=ivec.erase(it);   //erase返回被删元素之后元素的迭代器else++it;}for(auto c:ivec)cout<<c<<" ";

c) 接受一对迭代器的erase坂本允许我们删除一个范围内的元素。依旧是左闭合区间,栗子在下面

        vector<int>ivec{0,1,2,3,4,5,6,7,8,9};auto iter1=ivec.begin()+1,iter2=ivec.end()-2;               //*(ivec.end()-2)是8,前面的那个是1ivec.erase(iter1,iter2);for(auto c:ivec)cout<<c<<"";

d) 为了删除一个容器中的所有元素,既可以调用clear函数,也可以用begin和end获得的迭代器作为参数调用erase

   ivec1.clear();ivec2.erase(ivec2.begin(),ivec2.end());//等价调用,都是删除容器中所有元素

12. 改变容器大小

a) 用resize函数增大或缩小容器

 c.resize(n)   //调整c的大小为n个元素。//若n<c.size(),则多出的元素被丢弃。若必须添加新元素,对新元素进行值初始化c.resize(n,t) //调整c的大小为n个元素。任何新添加的元素都初始化为值t 

b) 如果当前大小大于所要求的大小,容器后部的元素会被删除;如果当前大小小于新大小,会将新元素添加到容器后部

    vector<int> ivec(10,42);              //10个int,每个int的值都是42ivec.resize(15);                      //将5个值为0的元素添加到ivec的末尾ivec.resize(25,-1);                   //将10个值为-1的元素添加到ivec的末尾ivec.resize(5);                        //从ivec的末尾删除20个元素

13. 容器操作可能使迭代器失效

a) 在向容器vector或string添加元素后,且存储空间被重新分配,指向容器的迭代器、指针或引用都会失效;如果存储空间未重新分配,指向插入位置之前的元素的迭代器、指针和引用仍有效,但指向插入位置之后元素的迭代器、指针和引用都会失效

b) 删除vector或string的一个元素后,指向被删元素之前元素的迭代器、指针和引用仍有效

c) 删除元素时,尾后迭代器总会失效

14. 构造string的其他方法

    string s1string s2(s1)string s2=s1                   //等价于s2(s1)string s3("value")string s3="value"string s4(n,'c')

string有与其他顺序容器相同的构造函数,在前面。下面是新内容

 string s(cp,n)                 //s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符string s(s2,pos2)              //s是strings2从下标pos2开始的字符的拷贝string s(s2,pos2,len2)          //s是string s2从下标pos2开始len2个字符的拷贝。不管len2的值是多少,构造函数至多拷贝s2.size()-pose2个字符

15. substr操作

   string s(cp,n)                 //s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符string s(s2,pos2)              //s是strings2从下标pos2开始的字符的拷贝string s(s2,pos2,len2) //s是string s2从下标pos2开始len2个字符的拷贝。不管len2的值是多少,构造函数至多拷贝s2.size()-pose2个字符string s("hello world");string s2=s.substr(0,5);       //s2=hellostring s3=s.substr(6); //s3=worldstring s4=s.substr(6,11);      //s4=world

substr操作返回一个string,它是原始string的一部分或全部的拷贝。可以传递给substr一个可选的开始位置和计数值

16. string搜索操作

a) string类提供了6个不同的搜索函数。每个搜索操作都返回一个string::size_type的值,表示匹配发生位置的下标;如果搜索失败,返回npos(初始化为值-1)

  s.find(args)                          //查找s中args第一次出现的位置s.rfind(args)                         //查找s中args最后一次出现的位置s.find_first_of(args)          //在s中查找args中任何一个字符第一次出现的位置s.find_last_of(args)           //在s中查找args中任何一个字符最后一次出现的位置s.find_first_not_of(args)      //在s中查找第一个不在args中的字符s.find_last_not_of(args)       //在s中查找最后一个不在args中的字符

args必须是以下形式之一:

   c,pos 从s中位置pos开始查找字符c。pos默认为0s2,pos 从s中位置pos开始查找字符串s2。pos默认为0 cp,pos 从s中位置pos开始查找指针cp指向的以空字符结尾的C风格字符串。pos默认为0 cp,pos,n 从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值

17.compare函数

a) 类似于strcmp,根据string是等于、大于还是小于参数指定的字符串,s.compare()返回0、正数或负数

b) 根据是要比较两个string还是一个string与一个字符数组,参数各有不同。以下是s.compare()的6种参数形式

 s2                     比较s和s2pos1,n1,s2             将s中从pos1开始的n1个字符与s2进行比较pos1,n1,s2,pos2,n2     将s中从pos1开始的n1个字符与s2中从pos2开始的n2个字符进行比较cp                     比较s与cp指向的以空字符结尾的字符数组pos1,n1,cp             将s中从pos1开始的n1个字符与cp指向的以空字符结尾的字符数组进行比较pos1,n1,cp,n2       将s中从pos1开始的n1个字符与指针cp指向的地址开始的n2个字符进行比较

18.容器适配器

a) 标准库定义了三个顺序容器适配器:stack、queue和priority_queue

b) 一种适配器本质上是一种机制,能使某种事物的行为看起来像另外一种事物一样。一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。例如,stack适配器接受一个顺序容器,并使其操作起来像一个stack一样

c) 所有容器适配器都支持的操作和类型:

  size_type        一种类型,足以保存当前类型的最大对象的大小value_type       元素类型container_type   实现适配器的底层容器类型A a;             创建一个名为a的空适配器A a(c);          创建一个名为a的适配器,带有容器c的一个拷贝关系运算符       每个适配器都支持所有关系运算符:==、!=、<、<=、>和>=,这些运算符返回底层容器的比较结果a.empty()        若a包含任何元素,返回false,否则返回truea.size()         返回a中的元素数目swap(a,b)        交换a和b的内容,a和b必须有相同类型,a.swap(b)         包括底层容器类型也必须相同

19.定义一个适配器

a) 每个适配器都定义了两个构造函数:默认构造函数创建一个空对象,接受一个容器的构造函数拷贝该容器来初始化适配器

b) 可以使用除array和forward_list之外的任何容器类型来构造stack

c) queue可以构造于list或deque之上,但不能基于vector构造

d) priority_queue可以构造于vector或string之上

20.栈适配器(可以在vector、deque或list之上时间)

a) stack类型定义在stack头文件中。以下是stack所支持的操作:

s.pop()             删除栈顶元素,但不返回该元素值
s.push(item)           创建一个新元素压入栈顶,该元素通过拷贝或移动item而来,
s.emplace(args)        或者由args构造
s.top()           返回栈顶元素,但不将元素弹出栈

下面是一个小栗子:

stack<int>intStack;   //空栈
for(size_t ix=0;ix!=10;ix++)
intStack.push(ix);             //intStack保存0到9十个数
while(!intStack.empty()){      //intStack中有值就继续循环
int value=intStack.top();
intStack.pop();                //弹出栈顶值的元素,继续循环
}

b) 每个容器适配器都基于底层容器类型的操作定义了自己的特殊操作。我们只可以使用适配器操作,不能使用底层容器类型的操作。例如,不能在一个stack上调用push_back,而必须使用stack自己的操作——push

21. 队列适配器(queue默认基于deque实现,priority_queue默认基于vector实现)

a) queue和priority_queue适配器定义在queue头文件中。以下是queue和priority_queue支持的操作

    q.pop()            返回queue的首元素或priority_queue的最高优先级的元素,但不返回此元素q.front()          返回首元素或尾元素,但不删除瓷元素q.back()           只适用于queueq.top()            返回最高优先级元素,但不删除该元素,只适用于priority_queueq.push(item)       在queue末尾或priority_queue中恰当的位置创建一个元素,q.emplace(args)    其值为item,或者由args构造

b) 标准库queue使用一种先进先出的存储和访问策略:进入队列的对象被放置到队尾,而离开队列的对象则从队首删除

c) priority_queue允许为队列中的元素建立优先级,新加入的元素会排在所有优先级比它低的已有元素之前

转载于:https://www.cnblogs.com/chuninggao/p/7275433.html

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

  1. 《C++Primer》第九章-顺序容器-学习笔记(1)-顺序容器定义与操作

    <C++Primer>第九章-顺序容器-学习笔记(1) 文章目录 <C++Primer>第九章-顺序容器-学习笔记(1) 摘要 顺序容器的定义 容器元素的初始化 将一个容器初始 ...

  2. C++Primer 第9章 顺序容器

    写在前面 到了,看来侯捷老师的STL,我对C++的标准库是有了极大的兴趣的,本章主要讲述的是标准库中的顺序容器的使用. 顺序容器 首先什么是顺序容器呢?是将数据以一定次序存储在内存当中,其数据的顺序不 ...

  3. C++ primer 第9章 顺序容器

    文章目录 顺序容器类型 确定使用哪种顺序容器 容器库概览 容器操作 迭代器 迭代器支持的所有操作 迭代器支持的所有运算 迭代器范围 对构成范围的迭代器的要求 标准库迭代器范围左闭右开的三种性质 容器定 ...

  4. C++ primer 第9章顺序容器 思维导图

  5. 《C++ Primer中文版(第五版)》 第九章 顺序容器

    <C++ Primer中文版(第五版)> 第九章 顺序容器 元素在顺序容器中的顺序与其加入容器时的位置相对应.关联容器中元素的位置由元素相关联的关键字值决定. 所有容器都共享公共的接口,不 ...

  6. C++primer第九章 顺序容器 9.5 额外的string操作

    除了顺序容器共同的操作之外,string类型还提供了一些额外的操作.这些操作中 的大部分要么是提供string类和C 风格字符数组之间的相互转换,要么是增加了允许我们用下标代替迭代器的版本. 标准库s ...

  7. C++primer第九章 顺序容器 9.3 顺序容器操作

    9.3顺序容器操作 顺序容器和关联容器的不同之处在于两者组织元素的方式.这些不同之处直接关系到了元素如何存储.访问.添加以及删除.上一节介绍了所有容器都支持的操作(罗列于表9.2(第295页)).本章 ...

  8. C++primer第九章 顺序容器 9.6 容器适配器

    9.6容器适配器 除了顺序容器外,标准库还定义了三个顺序容器适配器:stack.queue和priority_queue 适配器(adaptor)是标准库中的一个通用概念.容器.迭代器和函数<3 ...

  9. C++primer第九章 顺序容器 9.1 顺序容器概述 9.2容器库概览

    一个容器就是一些特定类型对象的集合.顺序容器(sequentialcontainer)为程序员提供了控制元素存储和访问顺序的能力.这种顺序不依赖于元素的值,而是与元素加入容器 时的位置相对应.与之相对 ...

最新文章

  1. 前端学习(529):等分布局存在间距得实现得解决方案
  2. html5中figure怎么用,figure 和 figcaption 元素的正确使用方式
  3. 2019秋季学习计划
  4. 马哥语录第一季第二集
  5. 数据可视化—如何利用”奶牛“,把图组合起来
  6. RBF神经网络算法分析与应用(适合快速入门实战)
  7. 网页中超长图片转成pdf文档
  8. kali2020.4 root权限下无法启动自带浏览器解决办法
  9. ios-获取相册相机图片
  10. 提问的智慧 | 推荐好文
  11. 清除服务器传输文件记录,Sqlserver2012清除服务器连接记录(服务器名称历史记录清除)...
  12. 气炸了!被交通银行这波操作~
  13. js的Canvas逆时针旋转90度
  14. google play连接超时_Google框架一键安装
  15. 苹果x屏幕出现一条绿线_苹果iPad换屏幕出现售后问题解答
  16. 抖音关键词排名怎么靠前,抖音关键词怎么优化?
  17. 西门子1200PLC程序恒压供水系统
  18. neosmart linux 光标,重装windows系统后原有的linux系统无法进入的解决办法。
  19. VVC 帧内预测代码 xPredIntraAng()函数
  20. Python 学习归纳

热门文章

  1. python操作RabbitMQ
  2. 【BZOJ1123】 [POI2008]BLO (tarjan)
  3. 回顾2013 - 技术上
  4. MYSQL 看书笔记
  5. ListView相关
  6. ZOJ 1049 2^x mod n = 1
  7. Oracle中若何间接运转OS敕令(下)
  8. 设备像素,设备独立像素,CSS像素
  9. SectionIndexer中的getSectionForPosition()与getPositionForSection()
  10. Spring整合Quartz定时发送邮件