C++标准库学习笔记:顺序容器part 2(vector是如何增长的、额外的string操作、容器适配器)
vector对象是如何增长的
- capacity和size: 容器的size是指它已经保存的元素的数目,而capacity则是在不分配新的内存的前提下它最多可以保存多少元素。
- 每个vector实现都可以选择自己的内存分配策略。但是必须遵守的一条原则是:只有当迫不得已时才可以分配新的内存空间。
额外的string操作
- 构造string的其他方法
string s(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(),构造函数的行为未定义,不管lens的值是多少,构造函数至多拷贝s2.size()-pos2个字符
- 子字符串操作
s.substr(pos, n) //返回一个string,包含s中从pos开始的n个字符的拷贝。pos的默认值为0。n的默认值为s.size()-pos,即拷贝从pos开始的所有字符。
- 改变string的其他方法
s.insert(s.size(), 5, '!'); //在s末尾插入五个感叹号
s.erase(s.size() - 5, 5); //从s删除最后五个字符
- append和replace操作
s.append(" ") //在字符串结尾添加字符串
s2.replace(11, 3, "5th") //从位置11开始,删除3个字符并插入“5th”
- string搜索操作
find函数
string name("AnnaBelle");
auto pos = name.find("Anna"); //返回第一个匹配位置的下标,否则返回npos,大小写敏感
//pos = 0
find_first_of操作:搜索给定字符串中任何一个字符匹配的位置
string numbers("0123456789"), name("r2d2"); //返回1,即,name中第一个数字的下标
auto pos = name.find_first_of(numbers);
find_first_not_of操作:搜索第一个不在参数中的字符
string dept("03714p3");
auto pos = dept.find_first_not_of(numbers); //返回5 - 字符‘p’的下标
-
compare函数:
-
数值转换
int i = 42;
string s = to_string(i); //将整数i转换为字符表示形式
double d = stod(s); //将字符串s转换为浮点数
//要转换为数值的string中第一个非空白字符必须是数值中可能出现的字符
string s2 = "pi = 3.14";
//转换s中以数字开始的第一个字符串,结果d = 3.14
d = stod(s2.substr(s2.find_first_of("+-.0123456789"))
容器适配器
-
三个容器适配器:stack、queue和priority_queue。
适配器是标准库中的一个通用概念,容器、迭代器和函数都有适配器。适配器支持的操作和类型:
-
定义一个适配器:
stack<int> stk(deq);
从deq拷贝元素到stk
默认情况下,stack和queue是基于deque实现的,priority_queue是在vector之上实现的。
stack<string, vector<string>> str_stk;
在vector上实现的空栈
stack<string, vector<string>> str_stk2(svec);
在vector上实现,初始化时保存svec的拷贝
所有适配器都要求容器具有添加和删除元素的能力,因此适配器不能构造在array之上,类似的,我们也不能用forward_list来构造适配器,因为所有适配器都要求容器具有添加、删除以及访问尾元素的能力。
stack只要求push_back、pop_back和back操作,因此可以使用除array和forward_list之外的任何容器来构造stack。queue适配器要求back、push_back、front和push_front,因此可以构造于list和deque之上,但不能基于vector构造。priority_queue除了front、push_back和pop_back操作之外还要求随机访问能力,因此它可以构造于vector或deque之上,但不能基于list构造。
- 几种适配器的使用
栈适配器:stack类型定义在stack头文件中。
声明:stack<int> intstack;
常用的栈操作:栈默认基于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构造
标准库queue使用一种先进先出的存储和访问策略;priority_queue允许我们为队列中的元素建立优先级,标准库在元素类型上使用 < 运算符来确定相对优先级。