你发现了奇怪的笔记五(C++)

顺序容器

  • 包括
解释
vector 可变大小数组。支持快速随机访问。在尾部之外的我i之插入或者删除元素可能很慢
deque 双端队列。支持快速随机访问。在头尾位置插入或删除很快
list 双向链表。只支持双向随机访问。在list中任何位置插入或删除操作速度都很快
forward_list 单向链表。只支持单向随机访问。在链表任何位置插入或删除操作速度都很快
array 固定大小数组。支持快速随机访问。不能添加或删除元素。和内置数组比,它支持拷贝和赋值。在类型匹配时
string 与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入或删除速度很快

容器操作

args见额外string操作

  • 类型别名
别名 解释
iterator 此容器类型的迭代器类型
const_iterator 可以读取元素,但不能修改元素的迭代器类型
size_type 无负号整数类型,足够保存此种容器类型最大可能容器的大小
difference_type 带符号整数类型,足够保存两个迭代器之间的距离
value_type 元素类型
reference 元素的左值类型;与value_type&含义相同
const_reference 元素的const左值类型(即,const value_type&)
  • 构造函数

每个容器类型都定义了一个默认构造函数,除array之外,其他容器默认构造函数都会创建一个指向类型的空容器,且都可以接受指定容器大小和元素初始值的参数.

seq只有顺序容器(array除外)的构造函数才能接受大小参数

函数 解释
C c; 默认构造函数,构造空容器
C c1(c2); 构造c2的拷贝c1
C c(b,e); 构造c,将迭代器b和e指向的范围内元素拷贝到c(array不支持)
C c(a,b,c...); 列表初始化c
C seq(n) seq包含n个元素,这些元素进行了值初始化;此构造函数是explicit的
C seq(n,t) seq包含n个初始化为t的元素
vector<int> ivec(10,-1);//10个int元素,每个值为-1)
deque<string> svec(10);//10个元素,每个都为空string

array<int,42>  //类型为:保存42个int的数组
array<int,42>::size_type i;//数组类型包括元素类型和大小
array<int>::size_type j;//错误:array<int>不是一个类型
array<int,42> digits = {0};//所有元素均为0
array<int,42> copy = digits;//正确,类型匹配,大小匹配,zhic赋值和拷贝。内置数值不行
  • 赋值与swap

注意:assign操作不适用于关联容器和array

操作 解释
c1 = c2; 将c1中的元素替换成c2的元素
c1 = {a,b,c...} 将c1中的元素替换成为列表中元素(array不适用)
a.swap(b) 交换a和b的元素。比b向a中拷贝元素块很多
swap(a,b) 与a.swap(b)等价
seq.assign(b,e) 将seq中的元素替换为迭代器b和e所表示的范围中的元素。迭代器b和e不能指向seq中的元素
seq.assign(il) 将seq中的元素替换为初始化列表il中的元素
seq.assign(n,t) 将seq中的元素替换为n个值为t的元素
  • 大小

resize不适用于array

shrink_to_fit只适用于vector,string,和deque。并且它只是一个请求,标准库并不保证退还内存。

capacity和reserve只适用于vector和string

reserve不会改变容器中元素的数量,它仅影响vector预先分配多大的内存空间。

方法 解释
c.size() c中元素的数目(array不支持)
c.max_size() c可保存的最大元素数目
c.empty() 若c中存储了元素,返回false,反之返回true
c.resize(n) 调整c的大小为n个元素。若n<c.size(),则多出的元素被丢弃。若必须添加新元素,对新元素进行值初始化。
c.resize(n,t) 调整c的大小为n个元素。任何新添加的元素都初始化为值t.
c.shrink_to_fit() 请将capacity()减少为于size()相同大小
c.capacity() 不重新分配内存空间的话,c可以保存多少元素
c.reserve(n) 分配至少能容纳n个元素的内存空间
  • 添加和删除(不适用array)

这些操作会改变容器的大小;

用来初始化、插入、删除的元素,实际上都是一个对象值的拷贝;

将元素插入到vector,deque和string中的任何位置都是合法的,但是可能非常的耗时;

forward_list有自己专业版本的insert,erase和emplace;

forward_list不支持push_back,pop_back和emplace_back;

vector和string不支持push_front,pop_front和emplace_front;

emplace是操作构造函数而不知拷贝元素;

方法 解释
c.insert(args) 将args中的元素拷贝进c
c.emplace(inits) 使用Inits构造c中的一个元素
c.erase(args) 删除args指定的元素
c.clear() 删除c中的所有元素。返回void
c.push_back(t) c.emplace_back(args) 在c的尾部创建一个值为t或者由args创建的元素。返回void
c.push_front(t) c.emplace_front(args) 在c的头部创建一个值为t或者由args创建的元素。返回void
c.insert(p,t) c.emplace(p,args) 在迭代器p指向的元素之前插入值为t或者由args创建的元素。返回新添加的第一个元素的迭代器
c.insert(p,n,t) 在迭代器p指向的元素之前插入n个值为t或者由args创建的元素。返回指向新添加ide元素迭代器;若n为0,则返回p
c.insert(p,b,e) 将迭代器b哈e指定的范围内的元素插入到迭代器p指向的元素之前。b和e不能指向c中的元素。返回指向新添加的第一个元素的迭代器;若范围为空,则返回p
c.insert(p.il) il是一个花括号包围的元素值列表。将这些给定值插入到迭代器p指向的元素之前。返回指向新添加的第一个元素的迭代器;若列表为空,则返回p
c.pop_back() 删除c中尾元素。若c为空,则函数行为未定义。函数返回void
c.pop_front() 删除c中首元素。若c未空,则函数行为未定义。函数返回void
c.erase(p) 删除迭代器p所指定的元素,返回一个指向被删除元素之后元素的迭代器,若p指向尾元素,则返回尾后(off-the-end)迭代器。若p是尾后迭代器,则函数行为未定义。
c.erase(b,e) 删除迭代器b和e所指定范围内的元素。返回一个指向最后一个被删除元素之后元素的迭代器,若e本身就是尾后迭代器,则函数也返回尾后迭代器。
list<string> lst;
auto iter = lst.begin();
iter = lst.insert(iter,word);//等价调用于push_front

class data
{
...
private:
	string book;
	int num;
	double price;
};
//在c的末尾构建一个data对象
//使用三个参数的data构造函数
c.push_back("c++",10,15.99);//错误:没有接受三个参数的push_back版本
c.push_back(data("C++",10,15.99));//正确:创建一个data对象给push_back

c.emplace_back("C++",10,15.99);//调用data(string,int,double)构造函数
c.emplace_back();//调用data();默认构造函数
c.emplace(iter,"C++");//调用data(string)构造函数
emplace函数在容器中直接构造元素。转递给emplace函数的参数必须与元素类型的构造函数匹配。
  • 关系运算符,自定义类型无法完成运算
符号 解释
==,!= 所有容器都支持
<,<=,>,>= 无序容器不支持
  • 获取迭代器
迭代器 解释
c.begin(),c.end() 返回指向c的首元素和尾元素之后的位置
c.cbegin(),c.cend() 返回const_iterator
  • 方向迭代器
迭代器 解释
reverse_iterator 按逆序寻址元素的迭代器
const_reverse_iterator 不能修改元素的逆序迭代器
c.rbegin(),c.rend() 返回指向c的尾元素和首元素之前位置的迭代器
c.crbegin(),c.crend() 返回const_revecse_iterator
  • 元素访问

at和下标操作只适用于string,vector和array

back不适用于forward_list

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

before_begin:首前迭代器。指向首元素前不存在的元素。和尾后迭代器类似。

方法 解释
lst.before_begin() lst.cbefore_begin() 返回指向链表首元素之前不存在的元素的迭代器。此迭代器不能解引用。cbefore_begin()返回一个const_iterator
lst.insert_after(p,t) lst.insert_after(p,n,t) lst.insert_after(p,b,e) lst.insert_after(p,il) 在迭代器p之后的位置插入元素。t是一个对象,n是数量,b和e是表示范围的一对迭代器(b和e不能指向lst内),il是一个花括号列表。返回一个指向最后一个插入元素的迭代器。如果范围为空,则返回p。若p为尾后迭代器,则函数行为未定义
emplace_after(p,args) 使用args在p指定的位置之后创建一个元素。返回一个指向 这个元素的迭代器。若p为尾后迭代器,则函数行为未定义
lst.erase_after(p) lst.erase_after(b,e) 删除p指向的位置之后的元素,或删除从b之后直到(但不包含)e之间的元素。返回一个指向被删除元素之后元素的迭代器,若不存在这样的元素,则返回尾后迭代器。如果p指向lst的尾元素或者是一个尾后迭代器,则函数行为未定义。

额外string操作

  • 构造方法

n,len2和pos2都是无符号值

方法 解释
string(cp,n) s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符
string s(s2,pos2) s是string s2从下标pos2开始字符的拷贝。若pos2>s2.size(),构造函数的行为未定义
string s(s2,pos2,len2) s是string s2从下标pos2开始len2个字符的拷贝。若pos2>s2.size(),构造函数的行为未定义。不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符
const char *cp ="hello world!!!";//以空字符结束的数组
char noNull[]={'h','i'};//不是以空字符结束
string s1(cp);//拷贝cp中的字符直到遇到空字符;s1=="hello world!!!"
string s2(noNull,2);//从noNull拷贝两个字符;s2=="hi"
string s3(noNull);//未定义:noNull不是以空字符结束
string s4(cp+6,5);//从cp[6]开始拷贝5个字符;s4=="world"
string s5(s1,6,5);//从s1[6]开始拷贝5个字符;s5=="world"
string s6(s1,6);//从s1[6]开始拷贝,直至s1末尾;s6=="world!!!"
string s7(s1,6,20);//正确,只拷贝到s1末尾;s7=="world!!!"
string s8(s1,16);//抛出一个out_of_range异常
  • substr操作
操作 解释
s.substr(pos,n) 返回一个string,包含s中从pos开始的n个字符拷贝。pos的默认值为0。n的默认值为s.size()-pos,即拷贝从pos,即拷贝从pos开始的所有字符。
string s("hello world");
string s2=s.substr(0,5);//s2=hello
string s3=s.substr(6);//s3=world
string s4=s.substr(8,11);//s3=world
string s5=s.substr(12);//抛出out_of_range异常
  • 修改string操作

args可以是下列形式之一;append和assign可以使用所有形式。

str不能与s相同,迭代器b和e不能指向s。

形式 解释
str 字符串str
str,pos,len str中从pos开始最多len个字
cp,len 从cp指向的字符数组的前(最多)len个字符
cp cp指向的以空字符结尾的字符数组
n,c n个字符c
b,e 迭代器b和e指定的范围内的字符
初始化列表 花括号包围的,以逗号分隔的字符列表
操作 解释
s.insert(pos,args) 在pos之前插入args指定的字符。pos可以是一个下标或一个迭代器。接受下标的版本返回一个指定s的引用;接受迭代器的版本返回指向第一个插入字符的迭代器。
s.erase(pos.len) 删除从位置pos开始的len个字符。如果len被省略,则删除从pos开始直至s末尾的所有字符。返回一个指向s的引用
s.assign(args) 将s中的字符替换为args指定的字符。返回一个指向s的引用。
s.append(args) 将args追加到s。返回一个指向s的引用。
s.replace(range,args) 删除s中范围range内的字符,替换为args指定的字符。range或者是一个下标和一个长度,或者是一对指向s的迭代器。返回一个指向s的引用
string s("C++"),s2=s;//将s和s2初始化为”C++“
s.insert(s.size()," Primer");//s=="C++ Primer"
s2.append(" Primer");//等价方法:s2=="C++ Primer"

//将"Primer"替换为plus
s.erase(4,6);//s=="C++"
s.insert(4," plus");//s=="C++ plus"
//从位置4开始,删除3个字符并插入plus
s2.replace(4,6," plus");//等价方法:s2=="C++ plus"
  • 搜索操作

每个搜索操作都返回一个string::size_type值,表示匹配发生位置的下标。如果搜索失败,则返回一个名为string::npos的static成员。

标准库将npos定义为一个const string::size_type类型,并初始化为值-1。由于npos是一个unsigned类型,此初始值以为着npos等于任何string最大的可能大小。因此最好不要采用int作为返回值

  • args必须是一下形式之一
形式 解释
c,pos 从s中位置pos开始查找字符c。pos默认为0(默认实参)
s2,pos 从s中位置pos开始查找字符串s2。pos默认为0
cp,pos 从s中位置pos开始查找指针cp指向的以空字符结尾的C风格字符串。pos默认为0
cp,pos,n 从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值
方法 解释
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.finid_first_not_of(args) 在s中查找第一个不在args中的字符
s.find_last_not_of(args) 在s中查找最后一个不在args中的字符
string numbers("0123456789"),name("r2d2");
//返回1,即name中第一个出现数字的下标
auto pos=name.find_first_of(numbers);

string dept("03714p3");
//返回5,即字符'p'的下标
auto pos=dept.find_first_not_of(numbers);
  • compare函数

除关系运算符外提供的函数。类似于strcmp,根据s是等于大于小于返回0,正数或负数

参数形式 解释
s2(s1.compare(s2)) 比较s1和s2
pos1,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个字符进行比较
  • 数值转换

如果string不能转换一个数值,这些函数抛出一个invalid_argument异常。如果转换得到的数值无法用任何类型来表示,则抛出一个out_of_range异常。

操作 解释
to_string(val) 一组重载函数,返回数值val的string表示。val可以是任何算术类型。对每个浮点类型和int或更大的整型,都有相应版本的to_string.与往常一样,小整数会被提升。
stoi(s,p,b) stol(s,p,b) stoul(s,p,b) stoll(s,p,b) stoull(s,p,b) 返回s的起始子串(表示整数内容)的数值,返回值类型分别是int,long,unsigned long,long long,unsigned long long。b表示转换所用的基数,默认值为10.p是size_t指针,用来保存s中第一个非数值字符的下标,p默认为0,即函数不保存下标
stof(s,p) stod(s,p) stold(s,p) 返回s的起始子串(表示浮点数内容)的数值,返回值类型分别是float,double或long double.参数p的作用与整数转换函数中一样

顺序容器迭代器适配器

stack和queue是基于deque实现的。priority_queue是在vector之上实现的。

除了顺序容器外,标准库还定义了三个顺序容器适配器:stack,queue和priority_queue.

容器,迭代器和函数都有适配器。本质上,一个适配器是一种机制。能使某种事物行为看起来像另一种十五一样。一个容器适配器接受一种已有的容器类型,使行为看起来像一种不同的类型。

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

栈默认基于deque实现,也可以在list或vector之上实现。

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

queue和priority_queue适配器定义在queue头文件中。

queue是基于deque实现的。priority_queue是在vector之上实现的。

queue也可以用list或vector实现,priority_queue也可以用deque实现。

操作 解释
q,pop() 返回queue的首元素或者priority_queue的最高优先级的元素,但不返回此元素
q.front() 返回首元素或尾元素,但不删除此元素
q.back() 只适用于---queue
q.top() 返回最高优先级元素,但不删除此元素 只适用priority_queue
q.push(item) q.emplace(args) 在queue末尾或priority_queue中恰当的位置创建一个元素,其值为Item,或者由args构造
原文地址:https://www.cnblogs.com/ysjcqs/p/cppnote5.html