简介
在本实验中,你将学习如何使用 C++ 标准模板库(STL)中的各种组件来创建和操作数据结构,例如向量(vector)、列表(list)、映射(map)、集合(set)等。你将探索这些 STL 容器的基本操作,包括添加、删除和遍历元素。此外,你还将了解如何利用 STL 算法对这些容器中的数据进行排序、搜索和处理。通过本实验的学习,你将深入理解如何利用 C++ STL 的强大功能和灵活性来构建高效且健壮的应用程序。
在本实验中,你将学习如何使用 C++ 标准模板库(STL)中的各种组件来创建和操作数据结构,例如向量(vector)、列表(list)、映射(map)、集合(set)等。你将探索这些 STL 容器的基本操作,包括添加、删除和遍历元素。此外,你还将了解如何利用 STL 算法对这些容器中的数据进行排序、搜索和处理。通过本实验的学习,你将深入理解如何利用 C++ STL 的强大功能和灵活性来构建高效且健壮的应用程序。
在本步骤中,你将学习 C++ 标准模板库(STL)中的 vector 容器,它是一种可以动态调整大小的数组。Vector 非常适合用于存储和操作元素集合。
首先,打开 WebIDE 并在 ~/project
目录下创建一个名为 vector_demo.cpp
的新文件。我们将逐步探索 vector 的基本操作。
touch ~/project/vector_demo.cpp
将以下代码添加到 vector_demo.cpp
文件中:
#include <iostream>
#include <vector>
int main() {
// 创建一个空的整数 vector
std::vector<int> numbers;
// 使用 push_back() 向 vector 添加元素
numbers.push_back(10);
numbers.push_back(20);
numbers.push_back(30);
// 打印 vector 的大小
std::cout << "Vector size: " << numbers.size() << std::endl;
// 使用索引访问元素
std::cout << "First element: " << numbers[0] << std::endl;
std::cout << "Second element: " << numbers[1] << std::endl;
// 使用范围-based for 循环遍历 vector
std::cout << "All elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 移除最后一个元素
numbers.pop_back();
// 检查移除元素后的新大小
std::cout << "Vector size after pop_back(): " << numbers.size() << std::endl;
return 0;
}
编译并运行程序:
g++ vector_demo.cpp -o vector_demo
./vector_demo
示例输出:
Vector size: 3
First element: 10
Second element: 20
All elements: 10 20 30
Vector size after pop_back(): 2
关于 vector 的关键点:
#include <vector>
引入 vector 库std::vector<type>
创建一个特定类型的 vectorpush_back()
向 vector 末尾添加元素size()
返回元素的数量[]
访问元素pop_back()
移除最后一个元素在本步骤中,你将学习 C++ STL 中的 list 容器,它实现了双向链表。List 提供了在任何位置高效插入和删除元素的操作。
打开 WebIDE 并在 ~/project
目录下创建一个名为 list_demo.cpp
的新文件:
touch ~/project/list_demo.cpp
将以下代码添加到 list_demo.cpp
文件中:
#include <iostream>
#include <list>
int main() {
// 创建一个空的整数 list
std::list<int> numbers;
// 向 list 添加元素
numbers.push_back(10); // 添加到末尾
numbers.push_front(5); // 添加到开头
numbers.push_back(20);
// 打印 list 的大小
std::cout << "List size: " << numbers.size() << std::endl;
// 遍历 list
std::cout << "List elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 移除元素
numbers.pop_front(); // 移除第一个元素
numbers.pop_back(); // 移除最后一个元素
// 在特定位置插入元素
auto it = numbers.begin();
numbers.insert(it, 15);
// 打印更新后的 list
std::cout << "Updated list: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 检查 list 是否为空
std::cout << "Is list empty? "
<< (numbers.empty() ? "Yes" : "No") << std::endl;
return 0;
}
编译并运行程序:
g++ list_demo.cpp -o list_demo
./list_demo
示例输出:
List size: 3
List elements: 5 10 20
Updated list: 15 10
Is list empty? No
关于 list 的关键点:
#include <list>
引入 list 库push_back()
向末尾添加元素push_front()
向开头添加元素pop_front()
和 pop_back()
移除元素insert()
允许在特定位置插入元素begin()
返回指向第一个元素的迭代器empty()
检查 list 是否为空在本步骤中,你将学习 C++ STL 中的 map 容器,它以排序且唯一的键顺序存储键值对。Map 非常适合用于创建字典或关联数组。
打开 WebIDE 并在 ~/project
目录下创建一个名为 map_demo.cpp
的新文件:
touch ~/project/map_demo.cpp
将以下代码添加到 map_demo.cpp
文件中:
#include <iostream>
#include <map>
#include <string>
int main() {
// 创建一个 map 来存储学生姓名和年龄
std::map<std::string, int> students;
// 插入键值对
students["Alice"] = 20;
students["Bob"] = 22;
students["Charlie"] = 21;
// 使用键访问值
std::cout << "Alice's age: " << students["Alice"] << std::endl;
// 检查键是否存在
if (students.count("David") == 0) {
std::cout << "David is not in the map" << std::endl;
}
// 遍历 map
std::cout << "All students:" << std::endl;
for (const auto& student : students) {
std::cout << student.first << ": " << student.second << std::endl;
}
// 移除一个键值对
students.erase("Bob");
// 检查 map 的大小
std::cout << "Number of students: " << students.size() << std::endl;
return 0;
}
编译并运行程序:
g++ map_demo.cpp -o map_demo
./map_demo
示例输出:
Alice's age: 20
David is not in the map
All students:
Alice: 20
Bob: 22
Charlie: 21
Number of students: 2
关于 map 的关键点:
#include <map>
引入 map 库map<KeyType, ValueType>
创建一个指定键和值类型的 map[]
访问值count()
检查键是否存在erase()
移除一个键值对size()
返回元素的数量在本步骤中,你将学习 C++ STL 中的 set 容器,它以排序顺序存储唯一元素。Set 会自动防止重复值,并按照特定顺序维护元素。
打开 WebIDE 并在 ~/project
目录下创建一个名为 set_demo.cpp
的新文件:
touch ~/project/set_demo.cpp
将以下代码添加到 set_demo.cpp
文件中:
#include <iostream>
#include <set>
int main() {
// 创建一个整数 set
std::set<int> numbers;
// 插入元素
numbers.insert(10);
numbers.insert(20);
numbers.insert(30);
numbers.insert(10); // 重复值,不会被添加
// 打印 set 的大小
std::cout << "Set size: " << numbers.size() << std::endl;
// 遍历 set
std::cout << "Set elements: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 检查元素是否存在
if (numbers.count(20) > 0) {
std::cout << "20 is in the set" << std::endl;
}
// 移除一个元素
numbers.erase(20);
// 检查移除后的 set 大小
std::cout << "Set size after removal: " << numbers.size() << std::endl;
// 清空 set
numbers.clear();
// 检查 set 是否为空
std::cout << "Is set empty? "
<< (numbers.empty() ? "Yes" : "No") << std::endl;
return 0;
}
编译并运行程序:
g++ set_demo.cpp -o set_demo
./set_demo
示例输出:
Set size: 3
Set elements: 10 20 30
20 is in the set
Set size after removal: 2
Is set empty? Yes
关于 set 的关键点:
#include <set>
引入 set 库set<type>
创建一个存储唯一元素的 setinsert()
添加元素(重复值会被忽略)count()
检查元素是否存在erase()
移除一个元素clear()
移除所有元素empty()
检查 set 是否为空在本步骤中,你将学习如何使用 STL 的 sort 算法对元素进行升序或降序排列。<algorithm>
库为各种容器提供了强大的排序功能。
打开 WebIDE 并在 ~/project
目录下创建一个名为 sort_demo.cpp
的新文件:
touch ~/project/sort_demo.cpp
将以下代码添加到 sort_demo.cpp
文件中:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 创建一个整数 vector
std::vector<int> numbers = {5, 2, 8, 1, 9, 3};
// 打印原始 vector
std::cout << "Original vector: ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 对 vector 进行升序排序
std::sort(numbers.begin(), numbers.end());
// 打印排序后的 vector
std::cout << "Sorted vector (ascending): ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 对 vector 进行降序排序
std::sort(numbers.begin(), numbers.end(), std::greater<int>());
// 打印降序排序后的 vector
std::cout << "Sorted vector (descending): ";
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
编译并运行程序:
g++ sort_demo.cpp -o sort_demo
./sort_demo
示例输出:
Original vector: 5 2 8 1 9 3
Sorted vector (ascending): 1 2 3 5 8 9
Sorted vector (descending): 9 8 5 3 2 1
关于 STL sort 的关键点:
<algorithm>
库以使用排序功能std::sort()
适用于多种容器std::greater<type>()
用于降序排序在本步骤中,你将学习如何使用 STL 算法在容器中查找和搜索元素。<algorithm>
库提供了强大的函数来搜索和定位元素。
打开 WebIDE 并在 ~/project
目录下创建一个名为 find_demo.cpp
的新文件:
touch ~/project/find_demo.cpp
将以下代码添加到 find_demo.cpp
文件中:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 创建一个整数 vector
std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 8};
// 查找特定元素的首次出现
auto it = std::find(numbers.begin(), numbers.end(), 8);
if (it != numbers.end()) {
std::cout << "First occurrence of 8 at index: "
<< std::distance(numbers.begin(), it) << std::endl;
}
// 计算元素的出现次数
int count = std::count(numbers.begin(), numbers.end(), 8);
std::cout << "Number of 8s in the vector: " << count << std::endl;
// 查找是否有元素大于 6
bool has_large_element = std::any_of(numbers.begin(), numbers.end(),
[](int n) { return n > 6; });
std::cout << "Vector has element > 6: "
<< (has_large_element ? "Yes" : "No") << std::endl;
// 查找最小和最大元素
auto min_it = std::min_element(numbers.begin(), numbers.end());
auto max_it = std::max_element(numbers.begin(), numbers.end());
std::cout << "Minimum element: " << *min_it << std::endl;
std::cout << "Maximum element: " << *max_it << std::endl;
return 0;
}
编译并运行程序:
g++ find_demo.cpp -o find_demo
./find_demo
示例输出:
First occurrence of 8 at index: 2
Number of 8s in the vector: 2
Vector has element > 6: Yes
Minimum element: 1
Maximum element: 9
关于 STL 搜索算法的关键点:
std::find()
查找元素的首次出现std::count()
计算元素的出现次数std::any_of()
检查是否有元素满足条件std::min_element()
和 std::max_element()
查找极值在本步骤中,你将学习使用不同的遍历技术来遍历 STL 容器的多种方法。我们将探索基于范围的 for 循环、迭代器以及传统的基于索引的遍历。
打开 WebIDE 并在 ~/project
目录下创建一个名为 iteration_demo.cpp
的新文件:
touch ~/project/iteration_demo.cpp
将以下代码添加到 iteration_demo.cpp
文件中:
#include <iostream>
#include <vector>
#include <list>
#include <map>
int main() {
// Vector 遍历
std::vector<int> numbers = {10, 20, 30, 40, 50};
// 方法 1: 基于范围的 for 循环(最现代且可读性高)
std::cout << "Vector iteration (range-based for):" << std::endl;
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
// 方法 2: 基于迭代器的遍历
std::cout << "Vector iteration (iterators):" << std::endl;
for (auto it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 方法 3: 基于索引的遍历
std::cout << "Vector iteration (index-based):" << std::endl;
for (size_t i = 0; i < numbers.size(); ++i) {
std::cout << numbers[i] << " ";
}
std::cout << std::endl;
// Map 遍历
std::map<std::string, int> ages = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 35}
};
std::cout << "Map iteration:" << std::endl;
for (const auto& pair : ages) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
编译并运行程序:
g++ iteration_demo.cpp -o iteration_demo
./iteration_demo
示例输出:
Vector iteration (range-based for):
10 20 30 40 50
Vector iteration (iterators):
10 20 30 40 50
Vector iteration (index-based):
10 20 30 40 50
Map iteration:
Alice: 25
Bob: 30
Charlie: 35
关于容器遍历的关键点:
auto
关键字有助于类型推断在本步骤中,你将学习两个重要的 STL 容器适配器:stack 和 queue。这些容器为后进先出(LIFO)和先进先出(FIFO)的数据管理提供了专门的操作。
打开 WebIDE 并在 ~/project
目录下创建一个名为 stack_queue_demo.cpp
的新文件:
touch ~/project/stack_queue_demo.cpp
将以下代码添加到 stack_queue_demo.cpp
文件中:
#include <iostream>
#include <stack>
#include <queue>
int main() {
// Stack 演示
std::stack<int> myStack;
// 向 stack 中添加元素
myStack.push(10);
myStack.push(20);
myStack.push(30);
std::cout << "Stack operations:" << std::endl;
std::cout << "Top element: " << myStack.top() << std::endl;
// 移除顶部元素
myStack.pop();
std::cout << "Top element after pop: " << myStack.top() << std::endl;
std::cout << "Stack size: " << myStack.size() << std::endl;
// Queue 演示
std::queue<std::string> myQueue;
// 向 queue 中添加元素
myQueue.push("Alice");
myQueue.push("Bob");
myQueue.push("Charlie");
std::cout << "\nQueue operations:" << std::endl;
std::cout << "Front element: " << myQueue.front() << std::endl;
std::cout << "Back element: " << myQueue.back() << std::endl;
// 移除队首元素
myQueue.pop();
std::cout << "Front element after pop: " << myQueue.front() << std::endl;
std::cout << "Queue size: " << myQueue.size() << std::endl;
return 0;
}
编译并运行程序:
g++ stack_queue_demo.cpp -o stack_queue_demo
./stack_queue_demo
示例输出:
Stack operations:
Top element: 30
Top element after pop: 20
Stack size: 2
Queue operations:
Front element: Alice
Back element: Charlie
Front element after pop: Bob
Queue size: 2
关于 stack 和 queue 的关键点:
push()
向顶部添加元素pop()
移除顶部元素top()
返回顶部元素push()
向队尾添加元素pop()
移除队首元素front()
返回队首元素back()
返回队尾元素size()
方法用于检查元素数量<stack>
和 <queue>
头文件在本步骤中,你将学习如何处理异常并确保 STL 容器的安全操作。异常处理有助于防止程序崩溃,并提供健壮的错误管理。
打开 WebIDE 并在 ~/project
目录下创建一个名为 exception_safety_demo.cpp
的新文件:
touch ~/project/exception_safety_demo.cpp
将以下代码添加到 exception_safety_demo.cpp
文件中:
#include <iostream>
#include <vector>
#include <stdexcept>
void demonstrateVectorSafety() {
std::vector<int> numbers;
try {
// 尝试从空 vector 中访问元素
std::cout << "Attempting to access element from empty vector:" << std::endl;
numbers.at(0); // 这将抛出 out_of_range 异常
}
catch (const std::out_of_range& e) {
std::cout << "Out of Range Error: " << e.what() << std::endl;
}
// 安全的元素添加
try {
numbers.push_back(10);
numbers.push_back(20);
std::cout << "Vector size: " << numbers.size() << std::endl;
// 安全的元素访问
std::cout << "First element: " << numbers.at(0) << std::endl;
std::cout << "Second element: " << numbers.at(1) << std::endl;
}
catch (const std::exception& e) {
std::cout << "An error occurred: " << e.what() << std::endl;
}
}
int main() {
// 演示 vector 的异常安全性
demonstrateVectorSafety();
return 0;
}
编译并运行程序:
g++ exception_safety_demo.cpp -o exception_safety_demo
./exception_safety_demo
示例输出:
Attempting to access element from empty vector:
Out of Range Error: vector
Vector size: 2
First element: 10
Second element: 20
关于容器异常安全性的关键点:
try-catch
块处理潜在的异常std::out_of_range
异常at()
方法会进行边界检查,而 []
操作符不会<stdexcept>
中的标准异常类在本实验中,你学习了 C++ 标准模板库(STL)的各个组件及其高效使用方法。你首先探索了 vector 容器,它是一种可以动态调整大小的数组。你学习了如何添加和移除元素、使用索引访问元素,以及使用基于范围的 for 循环遍历 vector。
接下来,你深入研究了 list 容器,它是一种双向链表的实现。你了解了如何执行常见的链表操作,例如插入、删除和遍历元素。你还探索了 map 容器,它允许存储键值对,以及 set 容器,它存储唯一元素。此外,你学习了如何使用 STL 算法(如 sort 和 find)来操作和搜索这些容器中的元素。最后,你探索了 stack 和 queue 容器,并讨论了在使用 STL 组件时异常安全的重要性。