STL常用容器
C++ 的标准模板库(STL)提供了多种容器来处理数据结构。常用的 STL 容器分为序列容器、关联容器和无序容器。每种容器都有其特定的 API 和使用场景。下面是常见容器的简要介绍和常用 API:
https://sunnywhy.com/course/1880/model/1884?itemId=1598 (晴问算法网址)
1. 序列容器
1.1. vector
vector
是动态数组,支持高效的随机访问和末尾插入。
- 常用 API:
push_back(value)
:在末尾插入元素。pop_back()
:删除末尾元素。size()
:返回容器中元素的数量。empty()
:判断容器是否为空。at(index)
:访问指定位置的元素(越界时抛出异常)。operator[]
:访问指定位置的元素(不会检查越界)。front()
:访问第一个元素。back()
:访问最后一个元素。clear()
:清空容器。insert(position, value)
:在指定位置插入元素。erase(position)
:删除指定位置的元素。
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
std::cout << vec[0] << std::endl; // 输出 1
1.2. list
list
是双向链表,适用于频繁插入和删除操作。
- 常用 API:
push_front(value)
:在头部插入元素。push_back(value)
:在尾部插入元素。pop_front()
:删除头部元素。pop_back()
:删除尾部元素。size()
:返回元素个数。empty()
:判断容器是否为空。clear()
:清空容器。insert(position, value)
:在指定位置插入元素。erase(position)
:删除指定位置的元素。
std::list<int> lst;
lst.push_back(10);
lst.push_front(5);
lst.pop_back();
1.3. deque
deque
是双端队列,支持高效的头尾插入和删除操作。
- 常用 API:
push_back(value)
:在尾部插入元素。push_front(value)
:在头部插入元素。pop_back()
:删除尾部元素。pop_front()
:删除头部元素。size()
:返回容器大小。at(index)
:访问指定位置的元素。front()
:访问第一个元素。back()
:访问最后一个元素。
std::deque<int> deq;
deq.push_back(5);
deq.push_front(1);
deq.pop_front();
1.4. stack
stack
是一个栈(LIFO),只能访问栈顶元素。
- 常用 API:
push(value)
:压入栈。pop()
:弹出栈顶元素。top()
:访问栈顶元素。empty()
:判断栈是否为空。size()
:返回栈中的元素数量。
std::stack<int> s;
s.push(10);
s.push(20);
std::cout << s.top() << std::endl; // 输出 20
1.5. queue
queue
是一个队列(FIFO),只能访问队头元素。
- 常用 API:
push(value)
:入队。pop()
:出队。front()
:访问队头元素。back()
:访问队尾元素。empty()
:判断队列是否为空。size()
:返回队列中元素数量。
std::queue<int> q;
q.push(10);
q.push(20);
std::cout << q.front() << std::endl; // 输出 10
2. 关联容器
2.1. set
set
是一个基于红黑树的集合,自动排序且不允许重复元素。
- 常用 API:
insert(value)
:插入元素。erase(value)
:删除指定元素。find(value)
:查找元素,返回迭代器。size()
:返回元素个数。empty()
:判断是否为空。clear()
:清空集合。
std::set<int> st;
st.insert(5);
st.insert(10);
st.erase(5);
2.2. map
map
是一个基于红黑树的有序字典,存储键值对,键不可重复。
- 常用 API:
insert({key, value})
:插入键值对。erase(key)
:删除指定键的元素。find(key)
:查找元素,返回迭代器。operator[]
:访问或插入元素。size()
:返回元素个数。empty()
:判断是否为空。
std::map<int, std::string> mp;
mp[1] = "one";
mp[2] = "two";
std::cout << mp[1] << std::endl; // 输出 "one"
2.3. multiset
multiset
是一个可以存储重复元素的有序集合。
- 常用 API:
insert(value)
:插入元素。erase(value)
:删除指定元素。find(value)
:查找元素,返回迭代器。
std::multiset<int> ms;
ms.insert(1);
ms.insert(1);
ms.erase(1);
2.4. multimap
multimap
是一个允许多个相同键的有序字典。
- 常用 API:
insert({key, value})
:插入键值对。erase(key)
:删除指定键的元素。find(key)
:查找元素,返回迭代器。
std::multimap<int, std::string> mmap;
mmap.insert({1, "a"});
mmap.insert({1, "b"});
3. 无序容器
3.1. unordered_set
unordered_set
是一个无序集合,底层使用哈希表。
- 常用 API:
insert(value)
:插入元素。erase(value)
:删除指定元素。find(value)
:查找元素,返回迭代器。
std::unordered_set<int> uset;
uset.insert(5);
uset.insert(10);
uset.erase(5);
3.2. unordered_map
unordered_map
是一个无序的字典,底层使用哈希表。
- 常用 API:
insert({key, value})
:插入键值对。erase(key)
:删除指定键的元素。find(key)
:查找元素,返回迭代器。operator[]
:访问或插入元素。
std::unordered_map<int, std::string> umap;
umap[1] = "one";
umap[2] = "two";
std::cout << umap[1] << std::endl; // 输出 "one"
4. 适配器容器
4.1. priority_queue
priority_queue
是一个基于堆的数据结构,提供对最大元素的高效访问。
- 常用 API:
push(value)
:插入元素。pop()
:删除最大元素。top()
:访问最大元素。empty()
:判断队列是否为空。size()
:返回队列大小。
std::priority_queue<int> pq;
pq.push(5);
pq.push(10);
std::cout << pq.top() << std::endl; // 输出 10
总结
C++ STL 提供了丰富的容器和 API,每个容器有不同的适用场景。你可以根据需要选择合适的容器来存储数据,并使用相应的 API 来操作这些容器。通过深入理解各容器的特性(如顺序性、查找效率、内存管理等),可以更好地设计和优化程序。
6.String字符串
在 C++ 中,std::string
是一个标准库提供的类,用于表示和操作文本字符串。它是基于字符数组(char[]
)实现的,但比原始 C 字符串更加安全、灵活且功能丰富。std::string
允许动态管理内存,并提供了多种操作字符串的成员函数和算法。
1. 声明和初始化 std::string
你可以通过不同的方式来声明和初始化 std::string
:
#include <iostream>
#include <string>
using namespace std;
int main() {
// 默认构造:空字符串
string str1;
// 使用 C 字符串初始化
string str2 = "Hello, world!";
// 使用指定长度和字符初始化
string str3(5, 'a'); // 生成 "aaaaa"
// 使用范围初始化(从另一个字符串的一部分)
string str4(str2.begin(), str2.begin() + 5); // 生成 "Hello"
cout << "str1: " << str1 << endl;
cout << "str2: " << str2 << endl;
cout << "str3: " << str3 << endl;
cout << "str4: " << str4 << endl;
return 0;
}
2. 常用的 std::string
成员函数
2.1 大小和容量
size()
或length()
:返回字符串中字符的数量。capacity()
:返回字符串的容量(即分配的内存大小)。empty()
:检查字符串是否为空。
string s = "Hello";
cout << s.size() << endl; // 5
cout << s.capacity() << endl; // 至少 5
cout << s.empty() << endl; // false
2.2 访问字符
operator[]
:访问指定位置的字符。at()
:访问指定位置的字符(带范围检查)。
string s = "Hello";
cout << s[0] << endl; // H
cout << s.at(1) << endl; // e
2.3 添加和修改
push_back()
:在字符串末尾添加一个字符。append()
或+=
:将一个字符串或字符追加到字符串的末尾。insert()
:在指定位置插入字符或字符串。replace()
:替换指定位置的子字符串。
string s = "Hello";
s.push_back('!');
cout << s << endl; // Hello!
s.append(" World");
cout << s << endl; // Hello! World
s += " Again";
cout << s << endl; // Hello! World Again
s.insert(6, "C++ ");
cout << s << endl; // Hello! C++ World Again
s.replace(6, 4, "Java");
cout << s << endl; // Hello! Java World Again
2.4 删除字符
pop_back()
:删除字符串末尾的一个字符。erase()
:删除指定位置的字符或子字符串。clear()
:清空字符串。
string s = "Hello!";
s.pop_back();
cout << s << endl; // Hello
s.erase(1, 3);
cout << s << endl; // Ho
s.clear();
cout << s.empty() << endl; // true
2.5 查找
find()
:查找子字符串或字符第一次出现的位置。rfind()
:查找子字符串或字符最后一次出现的位置。find_first_of()
、find_last_of()
:查找指定字符集中的任意一个字符。substr()
:返回指定位置的子字符串。
string s = "Hello, World!";
cout << s.find("World") << endl; // 7
cout << s.rfind("o") << endl; // 8
cout << s.find_first_of("aeiou") << endl; // 1
cout << s.substr(7, 5) << endl; // World
2.6 比较
compare()
:比较两个字符串的大小。==
、!=
、<
、<=
、>
、>=
:使用标准运算符进行比较。
string s1 = "Apple";
string s2 = "Banana";
cout << s1.compare(s2) << endl; // -1
cout << (s1 == s2) << endl; // 0 (false)
cout << (s1 < s2) << endl; // 1 (true)
2.7 转换
c_str()
:返回一个指向 C 字符串(以 null 结尾)的常量指针。data()
:返回一个指向字符数组的指针(通常与c_str()
相同,但不保证末尾有 null 字符)。
string s = "Hello";
const char* cstr = s.c_str();
cout << cstr << endl; // Hello
3. 字符串操作示例
3.1 拼接字符串
string s1 = "Hello, ";
string s2 = "World!";
string s3 = s1 + s2; // 使用 "+" 拼接
string s4 = s1.append(s2); // 使用 append 拼接
cout << s3 << endl; // Hello, World!
cout << s4 << endl; // Hello, World!
3.2 字符串切割(分割)
C++ 标准库本身没有直接的字符串切割函数,但你可以通过一些技巧来实现。
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
vector<string> split(const string& s, char delimiter) {
vector<string> result;
stringstream ss(s);
string token;
while (getline(ss, token, delimiter)) {
result.push_back(token);
}
return result;
}
int main() {
string str = "apple,banana,cherry";
vector<string> words = split(str, ',');
for (const string& word : words) {
cout << word << endl;
}
return 0;
}
4. 总结:std::string
常用的成员函数
- 初始化和赋值:
- 默认构造:
string s;
- 使用常量字符数组:
string s = "Hello";
- 指定字符:
string s(5, 'a');
生成 "aaaaa"
- 默认构造:
- 大小和容量:
size()
,length()
,capacity()
,empty()
- 访问字符:
operator[]
,at()
- 修改字符串:
push_back()
,append()
,insert()
,replace()
- 删除字符:
pop_back()
,erase()
,clear()
- 查找和子字符串:
find()
,substr()
,rfind()
- 比较字符串:
compare()
,==
,!=
,<
,>
,<=
,>=
- 转换:
c_str()
,data()
std::string
类的功能非常丰富,能够满足大多数日常字符串操作的需求。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!