【STL实用技巧】常用容器及相关问题和成员函数整理

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 【STL实用技巧】常用容器及相关问题和成员函数整理

string

1. string和char*有什么区别呢?

string是类,而char*是一个指向字符串的指针;string是一个char *类型的容器,它封装了char *,以及字符串操作相关的函数,并且string可以自动管理内存,不用考虑内存回收和访问越界问题。

2. string类中at成员函数和[]操作符区别?

当访问越界时,at可以抛出异常,[]直接编译报错。

3. 常用成员函数整理

1. //构造函数
2. string();
3. string(const string &str);
4. string(const char *s);   
5. string(int n,char c); 
6. 
7. //字符访问
8. const char &operator[] (int n) const;
9. const char &at(int n) const;
10. char &operator[] (int n);
11. char &at(int n);
12. 
13. //获取字符串const char *
14. const char *c_str() const;
15. 
16. //字符拷贝
17. int copy(char *s, int n, int pos=0) const;
18. 
19. //字符串长度
20. int length() const; 
21. 
22. //判断字符串是否为空
23. bool empty() const;
24. 
25. //字符串赋值
26. string &operator=(const string &s);
27. string &assign(const char *s); //该函数有多个重载
28. 
29. //字符串追加(连接)
30. string &operator+=(const string &s); 
31. string &operator+=(const char *s);
32. string &append(const char *s); //该函数有多个重载
33. 
34. //字符串比较
35. int compare(const string &s) const;  
36. int compare(const char *s) const; 
37. 
38. //查找
39. int find(char c,int pos=0) const; //该函数有多个重载
40. 
41. //替换
42. string &replace(int pos, int n, const char *s); //该函数有多个重载
43. 
44. //插入
45. string &insert(int pos, const char *s);
46. 
47. //删除
48. string &erase(int pos=0, int n=npos);

vector

1. vector为什么在尾部插入删除效率更高?

vector是一个动态单端数组,在尾部插入和删除效率更高,原因是在头部或者中间插入元素,那么插入位置后面的元素都要往后移一位,在头部或者中间删除一个元素,那么被删除元素后面的元素都会往前移动一位,这会产生大量的元素移动,所以效率和速度较低。在尾部插入或删除就不会产生这样的大量元素移动。

2. []和push_back的区别

[]操作时必须提前分配内存,而push_back不需提前分配内存,push_back是动态分配内存的;

[]可以随机存取,push_back只能在尾部插入元素;

1. vector<int> v(10);
2. v.push_back(1);
3. v.push_back(2);
4. //v.size() = 12  因为push_back是在尾部插入,会动态分配内存

3. 迭代器的指向

begin()指向第一个元素,而end()指向最后一个元素的后面位置。

容器元素 1 2 3
迭代器

🔺

begin()

🔺

end()

erase在删除元素后会自动使迭代器 it 后移,并返回移动后的迭代器位置.

1. //删除容器中的元素2
2. for(vector<int>::iterator it = v.begin(); it != v.end();)
3. {
4. if(*it == 2)
5.     {
6.         it = v.erase(it); //erase在删除元素后会自动使迭代器 it 后移,并返回移动后的迭代器位置
7.     }
8. else
9.     {
10.         it++;
11.     }
12. }

3. 常用成员函数

1. vector.size(); //容器大小     
2. vector.empty();  //容器是否为空    
3. vector.resize(len); //重新指定大小
4. vector.assign(beg,end); //将[beg, end)的值拷贝复制
5. vector.push_back(e); //在尾部放入元素
6. vector.at(index); //访问index处的元素 可抛出异常
7. vector[index]; //访问index处的元素
8. vector.front();  //返回头部元素
9. vector.back(); //返回尾部元素
10. vector.insert(pos,e); //在pos处插入e //该函数有多个重载
11. vector.clear(); //移除容器的所有数据
12. vec.erase(beg,end); //删除[beg, end)区间内数据 //该函数有多个重载

deque

双端数组,两端都可以插入删除。

1. deque.push_back(e);  //在容器尾部放入一个数据
2. deque.push_front(e); //在容器头部放入一个数据
3. deque.pop_back(); //删除容器最后一个数据
4. deque.pop_front(); //删除容器第一个数据
5. deque.at(index); //访问index处数据,可抛出异常
6. deque[index]; //访问index处数据,不可抛出异常 
7. deque.begin(); //返回容器中第一个元素的迭代器
8. deque.end(); //返回容器中最后一个元素的迭代器
9. deque.size();    
10. deque.empty();    
11. deque.resize(len);
12. deque.insert(pos, e); //含有多个重载
13. deque.clear();  
14. deque.erase(beg,end);  
15. deque.erase(pos);

stack

栈,后进先出。

1. stack.push(e); //入栈
2. stack.pop(); //出栈
3. stack.top(); //返回栈顶元素
4. stack.size(); //栈大小
5. stack.empty(); //栈判空

queue

queue队列,先进先出,固定一端进一端出,队尾进,队头出。priority_queue 是优先级队列。

1. queue.push(e); //往队尾添加元素
2. queue.pop(); //弹出队头的元素
3. queue.back(); 
4. queue.front();
5. queue.empty();  
6. queue.size();

list

双向链表,不支持随机访问,所以迭代器 it 不能 it+2 这种操作,一次只能移动一步 it++。

1. list.push_back(e); //尾插
2. list.push_front(e); //头插
3. list.pop_back(); //删除链表中尾部元素 
4. list.pop_front(); //删除链表中头部元素 
5. list.front(); //返回链表一个元素
6. list.back(); //返回链表最后一个元素
7. list.begin(); //返回链表第一个元素的迭代器
8. list.end(); //返回链表尾部元素的迭代器 
9. list.size(); 
10. list.empty(); 
11. list.resize(num); 
12. list.insert(pos,e); //含有多个重载
13. list.clear(); //移除链表的所有数据
14. list.erase(beg,end); //删除[beg, end)区间内数据 //多个重载
15. list.reverse(); //反转链表

set

集合容器,元素唯一且按一定规则有序排列,关于set排序功能的实现和函数对象可以参考本人这篇博客

image.png

multi_set 同一值可以出现多次。

map

键值对容器<key, value>,键值key唯一,且按照一定规则排序,可以根据key随机访问对应value,也就是说对key支持[]操作。multi_map,相同键值可以重复。

1. insert插入和[]插入有什么区别?

1. map<int, string> m;
2. 
3. m.insert(make_pair(1, "string1"));
4. m.insert(make_pair(1, "string2")); //插入失败
5. 
6. m[3] = "string3";
7. m[3] = "string4"; //覆盖原来的

2. 常用成员函数

1. //元素插入
2. map.insert(pair<int, string>(1, "111"));
3. map.insert(make_pair(1, "111"));
4. map.insert(map<int, string>::value_type(1, "111"));
5. map[1] = "111";
6. 
7. map.size();
8. map.empty();
9. map.clear(); 
10. map.erase(pos); 
11. map.find(key);

区别与相同点

1. 区别

vector stack queue deque list set multi_set map multi_map
数据结构

单端

数组

队列

双端

数组

双向链表 二叉树 二叉树 二叉树 二叉树
随机访问 支持 不支持 不支持 支持 不支持 不支持 不支持 对key支持 不支持

2. 相同点

所有容器提供的都是值语意(value),而不是引用语意(reference)。也就是说向容器中插入元素时,实行的是拷贝行为。所以,向容器中装入元素时必须保证元素能够被拷贝(必须提供拷贝构造函数实现深拷贝)。


相关文章
|
1月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
50 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
1月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
54 5
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
55 2
|
3月前
|
安全 编译器 容器
C++STL容器和智能指针
C++STL容器和智能指针
|
4月前
|
存储 语音技术 Python
语音识别,函数综合案例,黑马ATM,/t/t一个对不齐,用两个/t,数据容器入门,数据容器可以分为列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
语音识别,函数综合案例,黑马ATM,/t/t一个对不齐,用两个/t,数据容器入门,数据容器可以分为列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
|
4月前
|
存储 算法 C语言
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
|
4月前
|
设计模式 存储 缓存
【C++】详解STL容器之一的deque和适配器stack,queue
【C++】详解STL容器之一的deque和适配器stack,queue
|
4月前
|
存储 算法 C++
【C++】详解STL容器之一的 vector
【C++】详解STL容器之一的 vector
|
4月前
|
算法 C语言 C++
【C++】详解STL的容器之一:list
【C++】详解STL的容器之一:list
|
5月前
|
Kubernetes Go Docker
Kubernetes容器生命周期 —— 钩子函数详解(postStart、preStop)
4.2 结论 • postStart不会挡住主进程的启动; • postStart的执行相对于容器主进程的执行是异步的,它会在容器start后立刻触发,并不能保证PostStart钩子在容器ENTRYPOINT指令执行完毕之前运行。 5、使用场景
118 0