C++之容器 string、deque、set、map、list(multi)

本文详细介绍了STL中的几种重要容器,包括string的构造函数、成员函数、容量操作和迭代器;vector的初始化、元素访问、容量管理以及迭代器使用;list的特性和操作,如双向链表结构、插入删除操作;deque的构造、大小操作和双端插入删除特性;以及set和multiset的存储结构、插入删除和遍历方法。每个容器的特点和适用场景都有所阐述。
摘要由CSDN通过智能技术生成

STL:

08a6178d61a047eb98ab357cd6c9db26.png

String:

运算符重载:+ / = / += / []

注:at和[]的功能类似,就是返回所在位置的引用!

区别在于[]越界会直接报错!at越界会抛出异常!

2.1string类成员函数

构造函数类:

ddf35f0ebb2c49c491ce63a2535ab1bb.png 

析构函数:前面已经说过string类是管理动态增长字符数组,对于动态申请的空间,需要用到析构函数把它释放掉。不过这里我们无需操作,因为编译器会帮我们默认调用构造函数。

容量成员:

a9deb37323b044a7b1bfb016c417f056.png

两者区别:

reserve(): serve 是“保留”的词根,所以是用来预留容量的,并不会改变容器的有效元素个数。即用reserve()开辟空间时,仅改变capacity大小,与size无关。
resize(): size 是“大小”的意思,它主要用来调整容器有效元素的个数,有时候也会造成容量的改变。因此用resize()开辟空间时,会对增加的空间全部进行初始化,使得有效元素个数增加。

如果当前字符量小于n, reverse()对剩余容量不做处理,resize()则需要插入一些元素直到空间补满。

两个概念:
容量(capacity): 指容器在自由内存中获得存储空间的大小,容量为100时并不代表有100个元素,可能有效元素只有10个,剩下的90个都是闲置的未定义的内存空间。
大小(size): 指的是容器中实际(有效)元素的个数,当大小为100时,就代表容器中已存在100个元素,容量一定不小于100。

4.1迭代器介绍

string::iterator st1 = s1.begin();

迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。
迭代器按照定义分为以下四种:

 正向迭代器 :                           --容器类名:iterator 迭代器名;

常量正向迭代器   :                  -- 容器类名::const_iterator  迭代器名;

 反向迭代器  :                          --容器类名::reverse_iterator  迭代器名;

常量反向迭代器 :                     --容器类名::const_reverse_iterator  迭代器名;

e77ef26bbe06440484739fbe7ca9d287.png

6.string类对对象的修改操作 

66aa1c3b048f4827a4ecd479e64888a5.png

find_first_of:

从左往右开始匹配传入字符串或在对象中的任意一个的字符,一旦匹配就返回这个地址!

找不到就返回npos

getline、cin

  1. getline: 按行读取, 一次读取多个字符,直到读满N个,或者遇到指定的结束符(自定义的或者EOF或者换行符,不包括空白符)为止。
    形式:getline(字符指针,字符个数N,结束符);

  2. cin读取的话以及 scanf 时,遇到结束符(包括空白符)会终止,只读取空白符之前的部分

vector:

构造初始化:

b7598496de7f47098db30e1ebc61aeba.png

vector构造函数

(constructor)构造函数说明
vector()无参数构造
vector(size_type n,const value_type& val = value_type())用n个val来构造vector
vector(const vector& x)拷贝构造
vector(Inputlterator first,InputIterator last)迭代器区间来构造初始化

 访问元素:

operator[] 📌 注意事项:operator[] 会用断言检查越界,而 at() 会抛异常。
c.at(idx)传回索引 idx 所指的数据,如果 idx 越界,抛异常 out_of_range 

 vector 空间

容量空间接口说明
size获取数据个数
capacity获取容量大小
empty判断是否为空
resize     (重点)改变 vector 的 size
reserve   (重点)

改变 vector 放入 capacity

获取数据个数的 size()

获取 vector 最大存储的 max_size()

775528e274d543a590e8879182cc2385.png

string 的 resize 如果不指定 "填充值" ,默认给的是 \0

而 vector 的 resize 如果不指定,默认给的是其对应类型的缺省值作为 "填充值"

这里是 int 就是 0,如果是指针,对应的缺省值就是空指针。

Vector迭代器:

iterator 的使用接口说明
begin + end (重点)

获取第一个数据位置的 iterator/const_iterator,

获取最后一个数据的下一个位置的 iterator/const_iterator

rbegin + rend

获取最后一个数据位置的 reverse_iterator,

获取第一个数据前一个位置的 reverse_iterator

06811f9ab29c4e74a1f7ef3549d67154.png

 vector 增删查改

vector 增删查改接口说明
push_back(重点)尾插
pop_back  (重点)尾删
find            (#include algorithm)查找(注意这个是算法模块实现,不是 vector 的成员接口)
insert在 pos 之前插入 val
erase删除 pos 位置的数据
swap交换两个 vector 的数据空间
operator[]  (重点)

像数组一样访问

assign() 赋值

assign 可以把 vector 的内容覆盖掉。允许给一段区间覆盖

 该 find 和 erase配合使用内部是从 begin 到 end 进行一次遍历,其复杂度是 eq?O%28n%29 

// 如果有了判断,就不会中断,如果待删目标不存在,就不会去走 erase()  。 
// 因为 pos 如果找不到就会等于 end() 上的值,我们利用这一点进行 if 判断,

vector<int>::iterator pos = find(v.begin(), v.end(), 5);
if (pos != v.end()) {   v.erase(pos);   }

List:

两者的区别:

vector底层实现是数组;list是双向链表。
vector支持随机访问,list不支持。
vector是顺序内存,list不是。
vector在中间节点进行插入删除会导致内存拷贝,list不会。
vector一次性分配好内存,不够时才进行2倍扩容;list每次插入新节点都会进行内存申请。
6)vector随机访问性能好,插入删除性能差;list随机访问性能差,插入删除性能好。

两者相关应用:

vector拥有一段连续的内存空间,因此支持随机访问,如果需要高效的随即访问,而不在乎插入和删除的效率,使用vector。
list拥有一段不连续的内存空间,如果需要高效的插入和删除,而不关心随机访问,则应使用list。

list介绍 

list是序列容器,允许在序列中的任何位置执行固定O(1)时间复杂度的插入和删除操作,并在两个方向进行迭代。
list容器使用双链表实现;双链表将每个元素存储在不同的位置,每个节点通过next,prev指针链接成顺序表。
list与其他标准序列容器(array,vector和deque)相比,list通常可以在容器内的任何位置插入、提取和移动元素。
list与其他标准序列容器(array,vector和deque)相比,list和forward_list(单链表实现)的主要缺点是他们不能通过位置直接访问元素;例如,要访问列表中的第五个元素,必须从已知位置(开始或结束)迭代到该位置,需要哦线性时间开销。
存储密度低,list要使用一些额外的内容空间(next,prev)来保持与每个元素相关联(前后续的线性)的链接信息,从而导致存储小元素类型(如char,short,int等)的列表的存储密度低。
总的来说:list是双向带头循环列表,内存空间不连续、不支持随机访问。

 

3.list相关成员函数 

成员类型定义笔记
value_type第一个模板参数 (T)
allocator_type第二个模板参数(分配)默认值为:分配器<value_type>
参考allocator_type::参考对于默认分配器:value_type&
const_referenceallocator_type:const_reference对于默认分配器:常量 value_type&
指针allocator_type::p对于默认分配器:value_type*
const_pointerallocator_type:const_pointer对于默认分配器:常量value_type*
迭 代指向value_type的双向迭代器可转换为const_iterator
const_iterator用于构造value_type的双向迭代器
reverse_iteratorreverse_iterator<迭代器>
const_reverse_iteratorreverse_iterator<const_iterator>
difference_type有符号整数类型,与以下类型相同:iterator_traits<迭代器>::d验证类型通常与ptrdiff_t相同
size_type一种无符号整数类型,可以表示difference_type的任何非负值通常与size_t相同

3.2 list构造:

构造函数接口说明
list()构造空的list
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)用[first, last)区间中的元素构造list

4.1迭代器简介

迭代器和 vector一样

函数声明接口说明
1、begin返回第一个元素的迭代器
2、end返回最后一个元素下一个位置的迭代器
3、rbegin返回第一个元素的reverse_iterator,即end位置
4、rend返回最后一个元素下一个位置的reverse_iterator,即begin位置

5.元素访问 

元素访问功能
reference front();   返回到容器首元素的引用。
const_reference front() const; 返回到容器首元素的引用
reference back();    返回到容器中最后一个元素的引用。
const_reference back() const; 返回到容器中最后一个元素

list容量:

容量功能
bool empty() const;检查容器是否无元素,即是否 begin() == end() 
size_type size() const;    返回容器中的元素数,即 std::distance(begin(), end()) 
size_type max_size() const;  返回根据系统或库实现限制的容器可保有的元素最大数量,即对于最大容器的 std::distance(begin(), end()) 

7.元素修改 

修改器功能
void clear();  从容器擦除所有元素。此调用后 size() 返回零。
iterator insert( iterator pos, const T& value ); 在 pos 前插入 value 。
void insert( iterator pos, size_type count, const T& value );    在 pos 前插入 value 的 count 个副本。
template< class InputIt >   
void insert( iterator pos, InputIt first, InputIt last);  在 pos 前插入来自范围 [first, last) 的元素
iterator insert( const_iterator pos, std::initializer_list ilist );  在 pos 前插入来自 initializer_list ilist 的元素。
iterator erase( iterator pos );移除位于 pos 的元素。
iterator erase( iterator first, iterator last ); 移除范围 [first; last) 中的元素。
void pop_back();移除容器的末元素。
void pop_front();移除容器首元素。
void push_front( const T& value );前附给定元素 value 到容器起始。
void push_back( const T& value );后附给定元素 value 到容器尾。
void resize( size_type count );重设容器大小以容纳 count 个元素。
void resize( size_type count, T value = T() );count - 容器的大小,value - 用以初始化新元素的值
void swap( list& other );将内容与 other 的交换。

8.list的操作函数

操作函数功能
void merge( list& other );归并二个已排序链表为一个。链表应以升序排序。
void reverse();逆转容器中的元素顺序。
void unique();从容器移除所有相继的重复元素。只留下相等元素组中的第一个元素。
void sort();以升序排序元素。保持相等元素的顺序。用 operator< 比较元素

list与vector对比

17f1c38cdd1b46f19324a4a28a06ba20.png

deque容器

Vector容器是单向开口的连续内存空间,deque则是一种双向开口的连续线性空间。所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM1ODgzNDY0,size_16,color_FFFFFF,t_70

 deque构造函数

deque<T> deqT;默认构造形式
deque(beg, end);构造函数将[beg, end)区间中的元素拷贝给本身
deque(n, elem);构造函数将n个elem拷贝给本身
deque(const deque &deq);拷贝构造函数

 deque赋值操作

assign(beg, end);

将[beg, end)区间中的数据拷贝赋值给本身
assign(n, elem);将n个elem拷贝赋值给本身
deque& operator=(const deque &deq);重载等号操作符
swap(deq);将deq与本身的元素互换

deque大小操作

deque.size();返回容器中元素的个数
deque.empty();判断容器是否为空
deque.resize(num);重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
deque.resize(num, elem);重新指定容器的长度为num,若容器变长,则以elem值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除

deque双端插入和删除操作

push_back(elem);在容器尾部添加一个数据
push_front(elem);在容器头部插入一个数据
pop_back();删除容器最后一个数据
pop_front();删除容器第一个数据

deque数据存取

at(idx);返回索引idx所指的数据,如果idx越界,抛出out_of_range
operator[];返回索引idx所指的数据,如果idx越界,不抛出异常,直接出错
front();返回第一个数据。
back();返回最后一个数据

eque插入操作

insert(pos,elem);在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem);在pos位置插入n个elem数据,无返回值
insert(pos,beg,end);在pos位置插入[beg,end)区间的数据,无返回值

deque删除操作

clear();移除容器的所有数据
erase(beg,end);删除[beg,end)区间的数据,返回下一个数据的位置
erase(pos);删除pos位置的数据,返回下一个数据的位置

SET:

set的简介

set是按照一定的次序顺序存储数据的容器。
set的底层是通过二叉搜索树(红黑树)来实现的。
在默认情况下,set底层的二叉树遵循左子节点小于根节点、右子节点大于根节点且不能有相同节点的结构要求。
每个节点的值key具有const属性,不能被修改。
在set中查找某个特定数据的时间复杂度是O(NlogN)。
默认情况下,使用正向迭代器遍历set,是按照中序遍历进行的,也就是说会得到一组升序的数据。
set不可以存储相同的节点,但是multiset可以,multiset与set唯一的不同就是可以存储相同值的节点。

multiset的介绍:

  • 1、multiset是按照特定顺序存储元素的容器,其中元素是可以重复的。
  • 2、在multiset中,元素的value也会识别它(因为multiset中本身存储的就是<value, value>组成的键值对,因此value本身就是key,key就是value,类型为T). multiset元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除。
  • 3、在内部,multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序。
  • 4、multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列。
  • 5、multiset底层结构为二叉搜索树(红黑树)。
  • 注意:
  • 1、multiset中再底层中存储的是<value, value>的键值对
  • 2、mtltiset的插入接口中只需要插入即可
  • 3、与set的区别是,multiset中的元素可以重复,set是中value是唯一的
  • 4、使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
  • 5、multiset中的元素不能修改
  • 6、在multiset中找某个元素,时间复杂度为O(logN)
  • 7、multiset的作用:可以对元素进行排序

正是multiset允许了键值冗余,所以multiset的两个函数接口find和count与set的也是有区别的:

成员函数count功能说明
set对象值为val的元素存在则返回1,不存在则返回0
multiset对象返回set中值为x的元素的个数
成员函数find功能说明
set对象返回值为val的元素的迭代器位置
multiset对象返回底层搜索树中序的第一个值为val的元素的迭代器

1 构造及赋值相关接口函数

接口函数功能
set(const compare& comp = compare)默认构造,创建空树
set(InputIterator first, InputIterator last, ...)使用迭代器区间初始化
set(const set& x)拷贝构造
set& operator=(const set& x)赋值运算符重载函数

2 通过迭代器遍历set

默认情况下,使用正向迭代器遍历set是进行中序遍历,得到一组升序

2、set的迭代器
 

函数声明功能介绍
begin返回set中起始位置元素的迭代器
end返回set中最后一个元素后面的迭代器
cbegin返回set中起始位置元素的const迭代器
cend返回set中最后一个元素后面的const迭代器
rbegin返回set第一个元素的反向迭代器,即end
rend返回set最后一个元素下一个位置的反向迭代器,即begin
crbegin返回set第一个元素的反向const迭代器,即cend
crend返回set最后一个元素下一个位置的反向const迭代器,即cbegin

set的容量

函数声明功能介绍
bool empty ( ) const检测set是否为空,空返回true,否则返回true
size_type size() const返回set中有效元素的个数

3 结构修改相关接口函数

接口函数功能
pair<iterator,bool> insert(const Type& x)在插入值为x的节点
void insert(InputIterator first, InputIterator last)插入位于一段迭代器区间的数据集
size_t erase(const Type& x)删除指定值
void erase(iterator pos)通过给定迭代器位置删除特定节点
void clear()清空所有节点

这里需要注意insert函数的返回值:insert函数返回一键值对,pair中的first数据为iterator类型,如果成功插入节点(set中没有x),则返回新插入节点的位置的迭代器,如果插入节点失败,则返回与x值相同的节点的迭代器。pair中的second数据类型为bool,插入成功返回true,失败返回false。
erase返回被删除的节点的个数,因为set不允许有相同的节点,因此erase返回值只能是1或0,而multiset中erase的返回值则可以大于1,因为multiset中允许相同节点的存在。
当调用erase函数给定值不存在或迭代器位置不合法时:如果使用给定值x的方法删除set的节点且x不存在,那么函数不进行任何工作,直接返回。如果给定不合法的迭代器位置调用erase,那么程序会崩溃。

记录接口:

接口函数功能
iterator find(const Type& x) const查找特定数据x函数
size_t  count(const Type& x) const统计set中x出现的次数
iterator lower_bound (const Type& x) const返回小于或等于x的最小节点
iterator upper_bound (const Type& x) const返回大于x的最小节点
pair<iterator,iterator> equal_range (const Type& x) const返回包含x的区间

find函数如果没有找到值为x的节点,就返回end()的迭代器位置,如果要使用find函数的返回值,保险起见,应当检查 st.find(x) != st.end() 是否成立。
由于set中不允许有相同的节点,count的返回值只能是0或1。
equal返回的区间只包含一个数:[first, second) -- 左开右闭区间,*first = x。

Map/multimap

一. map容器
1. 容器介绍
map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair: typedef pair value_type;
在内部,map中的元素总是按照键值key进行比较排序的。
map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

注意事项

  • map中的的元素是键值对
  • map中的key是唯一的,并且不能修改
  • 默认按照小于的方式对key进行比较
  • map中的元素如果用迭代器去遍历,可以得到一个有序的序列
  • map的底层为平衡搜索树(红黑树),查找效率比较高
  • 支持[]操作符,operator[]中实际进行插入查找

multimap容器

multimap和map的唯一不同就是:map中的key是唯一的,而multimap中key是可以重复的。
multimap中没有重载operator[]操作

2. map的参数模板

 183b3cb2c26445d8854999ea7da73378.png

 3. 接口介绍和使用

Construct接口说明
map (const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type())构造空的map
map (InputIterator first, InputIterator last, const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type())用[first, last)区间的元素构造map
map (const map& x)拷贝构造

迭代器

Iterators接口说明
begin指向第一个元素的位置
end指向最后一个元素的下一个位置
rbegin反向迭代器, 指向最后一个元素
rend反向迭代器, 指向第一个元素前一个位置
cbegin
cend
crbegin下面这四个都是const迭代器, 与上面对应, 加上const所以无法修改内容
crend

map是按照key值有序的容器, 遍历相当于搜索树的中序遍历, 结果按照key有序, 默认是小于比较

特别要注意的是: map容器中的元素是pair类型, 使用迭代器取到的是pair类型, 还要通过pair的first和second来访问数据

元素访问

Element access接口说明
mapped_type& operator[] (const key_type& k)通过key找到对应的value, 返回value的引用
mapped_type& at (const key_type& k)返回key对应的value引用

operator[] 支持插入操作, 如果key不存在, 则直接进行插入操作

接口at()也是返回key对应的value引用和[]不同的是, 当key不存在时, 抛异常, 而不会进行插入

容量相关

Capacity接口说明
bool empty ( ) const检测map中的元素是否为空, 是返回true,否则返回false
size_type size() const返回map中有效元素的个数

修改操作

Modifiers接口说明
pair<iterator,bool> insert (const value_type& x )在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入元素的位置,bool代表释放插入成功
void erase ( iterator position )删除position位置上的元素
size_type erase ( constkey_type& x )删除键值为x的元素
void erase ( iterator first,iterator last )删除[first, last)区间中的元素
void swap (map<Key,T,Compare,Allocator>&mp )交换两个map中的元素
void clear ( )将map中的元素清空

其他接口:

Operations接口说明
iterator find (const key_type& x)在map中查找key为x的元素,找到返回该元素的位置的迭代器,否则返回end
size_type count (constkey_type& x ) const返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中
equal_range返回包含x的区间

析构函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值