3 STL常用容器
3.1 string容器
3.1.1 string基本概念
本质:
string是c++风格的字符串,而string本质上是一个类
*string和char 区别:
1. char* 是一个指针(C风格字符串)
2. string是一个类,类内部封装了char* ,管理这个字符串,是一个char* 型的容器(C++风格字符串)
特点:
string类内封装了很多成员方法
例如:查找find,拷贝copy,删除delete,替换replace,插入insert
string管理char* 所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责。
3.1.2 string构造函数
string(); //创建一个空的字符串 例如: string str;
string(const char* s); //使用字符串s初始化
string(const string& str); //使用一个string对象初始化另一个string对象
string(int n, char c); //使用n个字符c初始化
3.1.3 string赋值操作
赋值的函数原型:
string& operator=(const char* s); //char*类型字符串 赋值给当前的字符串
string& operator=(const string &s); //把字符串s赋给当前的字符串
string& operator=(char c); //字符赋值给当前的字符串
string& assign(const char *s); //把字符串s赋给当前的字符串
string& assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串
string& assign(const string &s); //把字符串s赋给当前字符串
string& assign(int n, char c); //用n个字符c赋给当前字符串
3.1.4 string字符串拼接
string& operator+=(const char* str); //重载+=操作符
string& operator+=(const char c); //重载+=操作符
string& operator+=(const string& str); //重载+=操作符
string& append(const char* s); //把字符串s连接到当前字符串结尾
string& append(const char* s, int n); //把字符串s的前n个字符连接到当前字符串的结尾
string& append(const string &s);//同operator+=(const string& str)
string& append(const string &s, int pos, int n);//字符串s中从pos开始的n个字符连接到字符串结尾
3.1.5 string查找和替换
查找:查找指定字符串是否存在,找到字符串后返回查找到的第一个位置,否则返回-1
//此处写出的都是常函数形式,使用此种形式可以防止对值的修改
int find(const string& str, int pos = 0) const;//查找str第一次出现的位置,从pos开始查找
int find(const char* s, int pos = 0) const;//查找s第一次出现的位置,从pos开始查找
int find(const char* s, int pos, int n) const;//从pos位置查找s的前n个字符第一次出现的位置
int find(const char c, int pos = 0) const;//查找字符c第一次出现的位置
//rfind从右往左查找 而find从左往右查找
int rfind(cosnt string& str, int pos = npos) const;//查找str最后一次出现的位置,从pos开始查找
int rfind(cosnt char* s, int pos = npos) const;//查找s最后一次出现的位置,从pos开始查找
int rfind(const char* s, int pos, int n) const;//从pos开始查找s的前n个字符最后一次出现的位置
int rfind(const char c, int pos = 0) const;//查找字符c最后一次出现位置
替换:在指定的位置替换字符串;指定从哪个位置开始,多少个字符,替换成哪个字符串
string& replace(int pos, int n, const string &str);//使用整个字符串str替换从pos开始的n个字符
string& replace(int pos, int n, const char* s);//使用整个字符串s替换从pos开始的n个字符
3.1.6 string字符串比较
主要的意义在于判断两字符串是否相等,判断大小意义不大
比较方式:按照字符的ASCII码进行比较
= 返回 0 > 返回 1 < 返回 -1
int compare(const string &s) const; //与字符串s进行比较
int compare(const char* s) const; //与字符串s进行比较
3.1.7 string字符存取
通过这种方式可以对指定位置的字符进行访问,并能完成修改等操作
//1. 通过[]方式获取字符
char& operator[](int n);
字符串名[n]; //实际使用时的形式
//2. 通过at方法获取字符
char& at(int n);
字符串名.at(n);
3.1.8 string字符串插入和删除
string& insert(int pos, const char* s); //插入字符串
string& insert(int pos, const string& str); //插入字符串
string& insert(int pos, int n, char c); //在指定位置插入n个字符c
string& erase(int pos, int n = npos); //删除从pos开始的n个字符
3.1.9 string子串
string substr(int pos = 0; int n = npos) const;返回由pos开始的n个字符组成的字符串
3.2 vector容器
3.2.1 vector基本概念
vector数据结构与数组相似,被称为单端数组;与数组的不同之处在于 数组是静态空间,而vector可以动态扩展
动态扩展:并非是在原空间之后续接新空间,而是寻找更大的内存空间,然后将原数据拷贝到新空间,释放原空间
3.2.2 vector构造函数
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(), v.end()); //将v[begin(),end()]区间中的元素拷贝给自身
vector(n, elem); //构造函数将n个elem拷贝给本身
vector(const vector &vec); //拷贝构造函数
3.2.3 vector赋值操作
vector& operator=(const vector &vec);//重载赋值操作符
assign(begin, end); //将[begin,end)区间的数据拷贝赋值给本身
assign(n, elem); //将n个elem拷贝赋值给本身
3.2.4 vector容量和大小
empty(); //判断容器是否为空,空返回1,非空返回0
capacity(); //容器的容量(容器最多可以容纳元素的个数)
size(); //返回容器中元素的个数
resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值0填充新位置;如果容器变短,末尾超出容器长度的元素会被删除
resize(int num, elem);//重新指定容器的长度为num,若容器变长,则以elem填充新位置;如果容器变短,末尾超出容器长度的元素会被删除
3.2.5 vector插入和删除
push_back(ele); //尾部插入元素ele
pop_bask(); //删除最后一个元素
insert(const_iterator pos, ele);//迭代器指向位置pos插入元素ele
insert(const_iterator pos, int count, ele);//迭代器指向位置pos插入count个元素ele
erase(const_iterator pos); //删除迭代器指向元素
erase(sont_iterator start, const_iterator end)//删除迭代器从start到end之间的所有元素
clear(); //删除容器中所有元素
3.2.6 vector数据存取
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
3.2.7 vector互换容器
实现两个容器内元素的互换
swap(vec); //将vec与本身的元素进行互换
巧用swap可以收缩内存空间:在capacity很大时,如果使用resize使得capacity>>size,(这样并不会改变容器的capacity),可以使用下列语句使capacity与size尺寸相同/相近:
vector<int>(v).swap(v); //vector<int>(v)是一个匿名对象,相当于使用v现在的数据新建了一个匿名对象,然后将其与现有的v进行互换
3.2.8 vector预留空间
减少vector在动态扩展容量时的扩展次数,如果数据量较大,可以在一开始利用reserve预留空间
reserve(int len); //容器预留len个元素长度,预留位置不进行初始化,元素不可访问
3.3 deque容器
读法:戴克
调用时需要包含deque头文件
3.3.1 deque容器基本概念
双端数组,可以对头端进行插入删除操作
deque和vector的区别:
- vector对于头部的插入删除效率低,数据量越大,效率越低
- deque相对而言,对头部的插入删除速度比deque快
- vector访问元素时的速度会比deque快,这和两者内部的实现有关
deque有个中控器,维护每段缓冲区中的内容,缓冲区用来存放真实数据;中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间
deque容器的迭代器也是支持随机访问的
3.3.2 deque构造函数
deque<T> //默认构造
deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身
deque(n, elem);//构造函数将n个elem拷贝给本身
deque(const deque &deq);//拷贝构造函数
3.3.3 deque赋值操作
deque& operator=(const deque &deq);//重载赋值操作符
assign(beg, end); //将[beg, end)区间内的数据拷贝赋值给本身
assign(n, elem); //将n个elem拷贝赋值给本身
3.3.4 deque大小操作
注意:deque容器没有容量(capacity)的概念
deque.empty(); //判断容器是否为空
deque.size(); //返回容器中元素的个数
deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置;如果容器变短,则末尾超出容器长度的元素被删除
deque.resize(num,elem);//重新指定容器的长度为num,若容器变长,则以elem填充新位置;若容器变短,则末尾超出容器长度的元素被删除
3.3.5 deque插入和删除
两端操作:
push_back(elem); //在容器尾部插入一个数据
push_front(elem); //在容器头部插入一个数据
pop_back(); //删除容器最后一个数据
pop_front(); //删除容器第一个数据
指定位置操作:
insert(pos, elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos, n, elem);//在pos卫视插入n个elem数据,无返回值
insert(pos, beg, end);//在pos位置插入[beg, end)区间的数据,无返回值
clear(); //清空容器的所有数据
erase(beg, end); //删除[beg, end)区间的数据,返回下一个数据的位置
erase(pos); //删除pos位置的数据,返回下一个数据的位置
插入和删除提供的位置是迭代器!
3.3.6 deque数据存取
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
3.3.7 deque排序
sort(iterator beg, iterator end) //对[beg, end)区间内的元素进行排序,默认为从小到大
对于支持随机访问迭代器的容器,都可以利用sort算法进行排序
3.4 stack容器
3.4.1 stack 栈
stack是一种先进后出(First In Last Out, FILO)的数据结构,只有一个出口
栈中只有栈顶的元素才可以被外界使用,因此栈不允许有遍历行为
栈中进入数据:入栈push 栈中弹出数据:出栈pop
3.4.2 stack常用的对外接口
//构造函数
stack<T> stk; //stack采用模板类实现,stack对象的默认构造形式
stack(const stack& stk);//拷贝构造函数
//赋值操作
stack& operator=(const stack& stk);//重载赋值操作符
//数据存取
push(elem); //向栈顶添加元素
pop(); //从栈顶移除第一个元素
top(); //返回栈顶元素
//大小操作
empty(); //判断堆栈是否为空
size(); //返回栈的大小
3.5 queue容器
3.5.1 queue 队列
Queue是一种先进先出(First In First Out, FIFO)的数据结构,有两个出口
队列容器允许从一端新增数据,从另一端移除数据
队列中只有队头和队尾才可以被外界使用,因此不允许有遍历行为
队列中进入数据:入队push 队列中弹出数据:出队pop
3.5.2 queue常用接口
//构造函数
queue<T> que; //queue采用模板类实现,queue对象的默认构造形式
queue(const queue& que);//拷贝构造函数
//赋值操作
queue& operator=(const queue& que);//重载赋值操作符
//数据存取
push(elem); //往队尾添加一个元素
pop(); //从队头移除一个元素
back(); //返回最后一个元素
front(); //返回第一个元素
//大小操作
empty(); //判断队列是否为空
size(); //返回队列的大小
3.6 list容器
3.6.1 list 链表
链表将数据进行链式存储。链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
链表由一系列结点组成;而结点包括两部分,一部分是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。
链表优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
链表缺点:容器遍历速度没有数组快(无法实现随机访问);占用空间比数组大
STL中的链表是一个双向循环链表。
由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器支支持前移和后移,属于双向迭代器
list的一个重要的性质是,插入和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的
3.6.2 list构造函数
list<T> lst; //list采用模板类实现,对象的默认构造形式
list(beg, end); //构造函数将[beg, end)区间中的元素拷贝给自身
list(n, elem); //构造函数将n个elem拷贝给本身
list(cosnt list &list);//拷贝构造函数
3.6.3 list赋值和交换
assign(beg, end); //将[beg, end)中的数据拷贝赋值给自身
assign(n, elem); //将n个elem拷贝赋值给自身
list &operator=(const list &list);//重载赋值操作符
swap(lst); //将lst与本身的元素互换
3.6.4 list大小操作
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(num); //重新指定容器的长度为num,如果容器变长,则以默认值填充新位置;容器变短则超出容器长度的元素会被删除
resize(num, elem);//重新指定容器的长度为num,如果容器变长,则以elem填充新位置;容器变短则超出容器长度的元素会被删除
3.6.5 list插入和删除
push_back(elem); //在容器尾部加入一个元素
pop_back(); //删除容器中最后一个元素
push_front(elem); //在容器开头插入一个元素
pop_front(); //从容器开头移除一个元素
insert(pos, elem); //在pos位置插入元素的拷贝并返回新数据的位置
insert(pos, n, elem); //在pos位置插入n个elem数据,无返回值
insert(pos, beg, end); //在pos位置插入[pos, end)区间的数据,无返回值
clear(); //移除容器中所有的数据
erase(beg, end); //删除[beg, end)区间的数据,并返回下一数据的位置
erase(pos); //删除pos位置的数据,返回下一个数据的位置
remove(elem); //删除容器中所有与elem值匹配的元素
3.6.6 list数据存取
list不支持随机访问,即不支持使用 [] 或 at(idx) 的形式访问元素,只可以使用 front(); 返回第一个元素、以及 back();返回最后一个元素
3.6.7 list反转排序
reverse(); //反转链表
sort(); //链表升序排序
所有不支持随机访问迭代器的容器,不可以使用标准算法,只可以使用内部提供的算法;此处需要调用的是 list.sort();,而并非前面所用的 sort(beg, end);
list.sort();支持传入参数,可以传入自定义大小比较的函数名来进行降序排序
bool myCompare(int v1, int v2){
return v1 > v2; //让第一个数大于第二个数,达成降序的效果
}
list1.sort(myCompare);
3.7 set/multiset 容器
3.7.1 set基本概念
所有元素会在插入时被自动排序。
set/multiset属于关联式容器,底层结构使用二叉树来实现。两者间的不同在于,set不允许容器中由重复的元素,但multiset允许容器中有重复的元素。
3.7.2 set构造和赋值
set<T> st; //默认构造函数
set(const set &st);//拷贝构造函数
set& operator=(const set& st);//重载赋值操作符
3.7.3 set大小和交换
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
3.7.4 set插入和删除
insert(elem); //在容器中插入元素
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end); //删除区间[beg, end)的所有元素,返回下一个元素的迭代器
erase(elem): //删除容器中值为elem的元素
3.7.5 set查找和统计
find(key); //查找key是否存在,若存在,返回该键元素的迭代器;若不存在返回set.end()
count(key); //统计key元素的个数
find()返回的结果是迭代器
count()对于set来说返回的结果是0或1
3.7.6 set和multiset的区别
set插入数据会返回一个表示插入是否成功的pair对组,不允许重复数据插入;
multiset插入数据直接返回迭代器,不会对重复数据进行检查
3.7.7 pair对组创建
对于成对出现的数据,利用对组可以返回两个数据
pair<type, type> p(value1, value2);
pair<type, type> p = make_pair(value1, value2);
访问对组中的元素:
p.first; //返回对组中的第一个元素
p.second; //返回对组中第二个元素
3.7.8 set容器排序
set默认排序规则是从小到大,利用仿函数可以改变排序规则
//内置数据类型,可以在建立set时指定排序规则
class MyCompare{
public:
bool operator()(int v1, int v2){
return v1 > v2;
}
};
set<int, MyCompare>s2; //s2的排序规则为从大到小降序
对于自定义数据类型,必须要使用仿函数指定排序规则才可以插入数据
set<Person, comparePerson>s;
3.8 map/multimap容器
3.8.1 map基本概念
map中所有元素都是pair,pair中第一个元素为key(键值),起到索引的作用,第二个元素为value(实值);所有元素都会根据元素的键值自动排序。
本质:map/multimap属于关联式容器,底层结构使用二叉树实现
优点:可以根据key值快速找到value值
map和multimap的区别:map不允许容器中有重复key值的元素;而multimap允许容器中有重复key值的元素
3.8.2 map构造和赋值
map<T1, T2> mp; //map默认构造函数
map(const map& map);//map拷贝构造函数
map& operator=(const map& mp);//重载赋值操作符
map中所有元素都成对出现,因此插入数据时应使用对组pair
3.8.3 map大小和交换
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(map); //交换两个map容器
3.8.4 map插入和删除
//map四种插入方式
m.insert(pair<T1, T2>(key1, value2));
m.insert(make_pair(key1, value2));
m.insert(pair<T1, T2>::value_type(key1, value2));
m[key1] = value1;//不建议使用[]插入,多用于使用key访问value
//删除操作
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg, end); //删除区间[beg, end)的所有元素,返回下一个元素的迭代器
erase(key); //删除容器中键值为key的元素,若不存在该键值则不删除
3.8.5 map查找和统计
find(key);//查找key是否存在,存在则返回该键元素的迭代器,不存在返回map.end()
count(key);//统计key的元素个数,对map而言值为0或1
3.8.6 map容器排序
map的默认排序顺序是从小到大升序排序,利用仿函数可以改变排序规则
本文详细介绍了C++STL中的几种主要容器,包括string的基本概念、构造函数、赋值操作、字符串拼接、查找和替换等;vector的动态扩展、构造函数、赋值操作、容量和大小管理、插入和删除等特性;deque的双端操作和数据存取;stack的栈操作接口;queue的队列操作接口;以及list的链表结构、插入删除操作;最后讨论了set和multiset、map和multimap的关联式容器特性和使用方法。
4万+

被折叠的 条评论
为什么被折叠?



