Appearance
STL标准库
概述
STL(Standard Template Library)是C++标准库的重要组成部分,提供了容器、迭代器、算法和函数对象等通用组件。
容器
vector动态数组
cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v1;
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
vector<int> v2 = {1, 2, 3, 4, 5};
cout << "v2大小: " << v2.size() << endl;
cout << "v2容量: " << v2.capacity() << endl;
cout << "元素访问:" << endl;
cout << "v2[0] = " << v2[0] << endl;
cout << "v2.at(1) = " << v2.at(1) << endl;
cout << "v2.front() = " << v2.front() << endl;
cout << "v2.back() = " << v2.back() << endl;
v2.insert(v2.begin() + 2, 100);
cout << "插入后: ";
for (int x : v2) cout << x << " ";
cout << endl;
v2.erase(v2.begin() + 2);
cout << "删除后: ";
for (int x : v2) cout << x << " ";
cout << endl;
v2.pop_back();
cout << "弹出后: ";
for (int x : v2) cout << x << " ";
cout << endl;
v2.clear();
cout << "清空后大小: " << v2.size() << endl;
return 0;
}list链表
cpp
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> lst = {1, 2, 3, 4, 5};
lst.push_front(0);
lst.push_back(6);
cout << "链表内容: ";
for (int x : lst) cout << x << " ";
cout << endl;
lst.insert(++lst.begin(), 100);
cout << "插入后: ";
for (int x : lst) cout << x << " ";
cout << endl;
lst.remove(100);
cout << "删除100后: ";
for (int x : lst) cout << x << " ";
cout << endl;
lst.reverse();
cout << "反转后: ";
for (int x : lst) cout << x << " ";
cout << endl;
lst.sort();
cout << "排序后: ";
for (int x : lst) cout << x << " ";
cout << endl;
lst.unique();
cout << "去重后: ";
for (int x : lst) cout << x << " ";
cout << endl;
return 0;
}deque双端队列
cpp
#include <iostream>
#include <deque>
using namespace std;
int main() {
deque<int> dq = {2, 3, 4};
dq.push_front(1);
dq.push_back(5);
cout << "双端队列: ";
for (int x : dq) cout << x << " ";
cout << endl;
cout << "front: " << dq.front() << endl;
cout << "back: " << dq.back() << endl;
dq.pop_front();
dq.pop_back();
cout << "弹出两端后: ";
for (int x : dq) cout << x << " ";
cout << endl;
return 0;
}stack栈
cpp
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
s.push(10);
s.push(20);
s.push(30);
cout << "栈顶: " << s.top() << endl;
cout << "大小: " << s.size() << endl;
while (!s.empty()) {
cout << "弹出: " << s.top() << endl;
s.pop();
}
return 0;
}queue队列
cpp
#include <iostream>
#include <queue>
using namespace std;
int main() {
queue<int> q;
q.push(10);
q.push(20);
q.push(30);
cout << "队首: " << q.front() << endl;
cout << "队尾: " << q.back() << endl;
cout << "大小: " << q.size() << endl;
while (!q.empty()) {
cout << "出队: " << q.front() << endl;
q.pop();
}
return 0;
}priority_queue优先队列
cpp
#include <iostream>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
int main() {
priority_queue<int> pq;
pq.push(30);
pq.push(10);
pq.push(50);
pq.push(20);
cout << "大顶堆出队顺序:" << endl;
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
cout << endl;
priority_queue<int, vector<int>, greater<int>> minPQ;
minPQ.push(30);
minPQ.push(10);
minPQ.push(50);
minPQ.push(20);
cout << "小顶堆出队顺序:" << endl;
while (!minPQ.empty()) {
cout << minPQ.top() << " ";
minPQ.pop();
}
cout << endl;
return 0;
}set集合
cpp
#include <iostream>
#include <set>
using namespace std;
int main() {
set<int> s = {5, 3, 1, 4, 2};
s.insert(6);
s.insert(3);
cout << "集合内容(自动排序): ";
for (int x : s) cout << x << " ";
cout << endl;
auto it = s.find(3);
if (it != s.end()) {
cout << "找到元素: " << *it << endl;
}
s.erase(3);
cout << "删除3后: ";
for (int x : s) cout << x << " ";
cout << endl;
cout << "count(5): " << s.count(5) << endl;
auto range = s.equal_range(4);
cout << "equal_range(4): [" << *range.first << ", " << *range.second << "]" << endl;
return 0;
}map映射
cpp
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> scores;
scores["张三"] = 85;
scores["李四"] = 90;
scores["王五"] = 78;
scores.insert({"赵六", 88});
scores.emplace("钱七", 95);
cout << "成绩表:" << endl;
for (const auto &p : scores) {
cout << p.first << ": " << p.second << endl;
}
cout << "\n张三的成绩: " << scores["张三"] << endl;
cout << "李四的成绩: " << scores.at("李四") << endl;
auto it = scores.find("王五");
if (it != scores.end()) {
cout << "找到王五: " << it->second << endl;
}
scores.erase("王五");
cout << "\n删除王五后的人数: " << scores.size() << endl;
if (scores.count("张三")) {
cout << "张三在成绩表中" << endl;
}
return 0;
}unordered_map哈希映射
cpp
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
unordered_map<string, int> um;
um["apple"] = 1;
um["banana"] = 2;
um["cherry"] = 3;
cout << "哈希映射内容:" << endl;
for (const auto &p : um) {
cout << p.first << ": " << p.second << endl;
}
cout << "\n查找 banana: " << um["banana"] << endl;
cout << "桶数量: " << um.bucket_count() << endl;
cout << "负载因子: " << um.load_factor() << endl;
return 0;
}迭代器
迭代器类型
cpp
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
cout << "正向迭代器: ";
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl;
cout << "反向迭代器: ";
for (auto it = v.rbegin(); it != v.rend(); ++it) {
cout << *it << " ";
}
cout << endl;
auto it = v.begin();
advance(it, 2);
cout << "advance后: " << *it << endl;
cout << "distance: " << distance(v.begin(), it) << endl;
auto nextIt = next(it);
cout << "next: " << *nextIt << endl;
auto prevIt = prev(it);
cout << "prev: " << *prevIt << endl;
return 0;
}算法
排序算法
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
vector<int> v1 = v;
sort(v1.begin(), v1.end());
cout << "升序排序: ";
for (int x : v1) cout << x << " ";
cout << endl;
vector<int> v2 = v;
sort(v2.begin(), v2.end(), greater<int>());
cout << "降序排序: ";
for (int x : v2) cout << x << " ";
cout << endl;
vector<int> v3 = v;
partial_sort(v3.begin(), v3.begin() + 3, v3.end());
cout << "部分排序(前3个最小): ";
for (int x : v3) cout << x << " ";
cout << endl;
vector<int> v4 = v;
nth_element(v4.begin(), v4.begin() + 4, v4.end());
cout << "第5小元素: " << v4[4] << endl;
return 0;
}查找算法
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
auto it = find(v.begin(), v.end(), 5);
if (it != v.end()) {
cout << "找到5,位置: " << distance(v.begin(), it) << endl;
}
auto it2 = find_if(v.begin(), v.end(), [](int x) { return x > 5; });
if (it2 != v.end()) {
cout << "第一个大于5的数: " << *it2 << endl;
}
bool found = binary_search(v.begin(), v.end(), 6);
cout << "二分查找6: " << (found ? "找到" : "未找到") << endl;
auto range = equal_range(v.begin(), v.end(), 5);
cout << "equal_range(5): [" << *range.first << ", " << *range.second << "]" << endl;
int cnt = count(v.begin(), v.end(), 5);
cout << "5出现次数: " << cnt << endl;
int cnt2 = count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
cout << "偶数个数: " << cnt2 << endl;
return 0;
}修改算法
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
vector<int> v2(v.size());
copy(v.begin(), v.end(), v2.begin());
cout << "复制后v2: ";
for (int x : v2) cout << x << " ";
cout << endl;
fill(v2.begin(), v2.end(), 0);
cout << "填充后v2: ";
for (int x : v2) cout << x << " ";
cout << endl;
transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });
cout << "transform后v: ";
for (int x : v) cout << x << " ";
cout << endl;
replace(v.begin(), v.end(), 4, 100);
cout << "替换后v: ";
for (int x : v) cout << x << " ";
cout << endl;
vector<int> v3 = {1, 2, 2, 3, 3, 3, 4};
auto last = unique(v3.begin(), v3.end());
v3.erase(last, v3.end());
cout << "去重后v3: ";
for (int x : v3) cout << x << " ";
cout << endl;
reverse(v.begin(), v.end());
cout << "反转后v: ";
for (int x : v) cout << x << " ";
cout << endl;
return 0;
}排列算法
cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v = {1, 2, 3};
cout << "全排列:" << endl;
int count = 0;
do {
cout << ++count << ": ";
for (int x : v) cout << x << " ";
cout << endl;
} while (next_permutation(v.begin(), v.end()));
vector<int> v2 = {3, 2, 1};
prev_permutation(v2.begin(), v2.end());
cout << "prev_permutation后: ";
for (int x : v2) cout << x << " ";
cout << endl;
return 0;
}函数对象
lambda表达式
cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int main() {
auto add = [](int a, int b) { return a + b; };
cout << "add(3, 4) = " << add(3, 4) << endl;
int x = 10;
auto addX = [x](int a) { return a + x; };
cout << "addX(5) = " << addX(5) << endl;
auto addRef = [&x](int a) {
x = a + x;
return x;
};
cout << "addRef(5) = " << addRef(5) << ", x = " << x << endl;
vector<int> v = {5, 2, 8, 1, 9};
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
cout << "降序排序: ";
for (int n : v) cout << n << " ";
cout << endl;
int sum = 0;
for_each(v.begin(), v.end(), [&sum](int n) { sum += n; });
cout << "总和: " << sum << endl;
return 0;
}function和bind
cpp
#include <iostream>
#include <functional>
#include <string>
using namespace std;
int add(int a, int b) {
return a + b;
}
class Calculator {
public:
int multiply(int a, int b) {
return a * b;
}
};
int main() {
function<int(int, int)> func1 = add;
cout << "func1(3, 4) = " << func1(3, 4) << endl;
function<int(int, int)> func2 = [](int a, int b) { return a - b; };
cout << "func2(10, 3) = " << func2(10, 3) << endl;
Calculator calc;
function<int(int, int)> func3 = bind(&Calculator::multiply, &calc, placeholders::_1, placeholders::_2);
cout << "func3(3, 4) = " << func3(3, 4) << endl;
auto addFive = bind(add, placeholders::_1, 5);
cout << "addFive(10) = " << addFive(10) << endl;
return 0;
}智能指针
unique_ptr
cpp
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class Resource {
public:
string name;
Resource(string n) : name(n) {
cout << "创建: " << name << endl;
}
~Resource() {
cout << "销毁: " << name << endl;
}
};
int main() {
{
unique_ptr<Resource> ptr1 = make_unique<Resource>("资源1");
cout << "ptr1: " << ptr1->name << endl;
unique_ptr<Resource> ptr2 = move(ptr1);
cout << "移动后 ptr2: " << ptr2->name << endl;
cout << "ptr1 是否为空: " << (ptr1 ? "否" : "是") << endl;
}
cout << "--- 离开作用域 ---" << endl;
return 0;
}shared_ptr
cpp
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class SharedResource {
public:
string name;
SharedResource(string n) : name(n) {
cout << "创建: " << name << endl;
}
~SharedResource() {
cout << "销毁: " << name << endl;
}
};
int main() {
shared_ptr<SharedResource> ptr1 = make_shared<SharedResource>("共享资源");
cout << "引用计数: " << ptr1.use_count() << endl;
{
shared_ptr<SharedResource> ptr2 = ptr1;
cout << "ptr2创建后引用计数: " << ptr1.use_count() << endl;
shared_ptr<SharedResource> ptr3 = ptr1;
cout << "ptr3创建后引用计数: " << ptr1.use_count() << endl;
}
cout << "离开作用域后引用计数: " << ptr1.use_count() << endl;
return 0;
}weak_ptr
cpp
#include <iostream>
#include <memory>
using namespace std;
class Node {
public:
string name;
weak_ptr<Node> next;
Node(string n) : name(n) {
cout << "创建节点: " << name << endl;
}
~Node() {
cout << "销毁节点: " << name << endl;
}
};
int main() {
auto node1 = make_shared<Node>("节点1");
auto node2 = make_shared<Node>("节点2");
node1->next = node2;
node2->next = node1;
cout << "node1引用计数: " << node1.use_count() << endl;
cout << "node2引用计数: " << node2.use_count() << endl;
if (auto locked = node1->next.lock()) {
cout << "node1的下一个节点: " << locked->name << endl;
}
return 0;
}实践示例
学生成绩管理系统
cpp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <memory>
#include <iomanip>
using namespace std;
class Student {
public:
int id;
string name;
map<string, double> scores;
Student(int i, string n) : id(i), name(n) {}
void addScore(const string &subject, double score) {
scores[subject] = score;
}
double getAverage() const {
if (scores.empty()) return 0;
double sum = 0;
for (const auto &p : scores) {
sum += p.second;
}
return sum / scores.size();
}
double getTotal() const {
double sum = 0;
for (const auto &p : scores) {
sum += p.second;
}
return sum;
}
void display() const {
cout << "学号: " << id << ", 姓名: " << name << endl;
cout << "成绩: ";
for (const auto &p : scores) {
cout << p.first << "=" << p.second << " ";
}
cout << "\n总分: " << getTotal() << ", 平均分: " << fixed << setprecision(2) << getAverage() << endl;
}
};
class GradeManager {
private:
vector<shared_ptr<Student>> students;
public:
void addStudent(int id, const string &name) {
students.push_back(make_shared<Student>(id, name));
cout << "添加学生成功: " << name << endl;
}
void addScore(int id, const string &subject, double score) {
auto it = find_if(students.begin(), students.end(),
[id](const shared_ptr<Student> &s) { return s->id == id; });
if (it != students.end()) {
(*it)->addScore(subject, score);
cout << "添加成绩成功" << endl;
} else {
cout << "未找到学生" << endl;
}
}
void displayAll() const {
cout << "\n" << string(70, '=') << endl;
cout << left << setw(8) << "学号"
<< setw(12) << "姓名"
<< setw(10) << "总分"
<< setw(10) << "平均分" << endl;
cout << string(70, '-') << endl;
for (const auto &s : students) {
cout << left << setw(8) << s->id
<< setw(12) << s->name
<< setw(10) << fixed << setprecision(1) << s->getTotal()
<< setw(10) << fixed << setprecision(2) << s->getAverage() << endl;
}
cout << string(70, '=') << endl;
}
void sortByTotal() {
sort(students.begin(), students.end(),
[](const shared_ptr<Student> &a, const shared_ptr<Student> &b) {
return a->getTotal() > b->getTotal();
});
cout << "按总分排序完成" << endl;
}
void findStudent(int id) const {
auto it = find_if(students.begin(), students.end(),
[id](const shared_ptr<Student> &s) { return s->id == id; });
if (it != students.end()) {
cout << "\n找到学生:" << endl;
(*it)->display();
} else {
cout << "未找到学号为 " << id << " 的学生" << endl;
}
}
void getTopStudents(int n) const {
vector<shared_ptr<Student>> sorted = students;
sort(sorted.begin(), sorted.end(),
[](const shared_ptr<Student> &a, const shared_ptr<Student> &b) {
return a->getTotal() > b->getTotal();
});
cout << "\n前" << n << "名学生:" << endl;
int count = min(n, (int)sorted.size());
for (int i = 0; i < count; i++) {
cout << "第" << (i + 1) << "名: " << sorted[i]->name
<< " (总分: " << sorted[i]->getTotal() << ")" << endl;
}
}
};
int main() {
GradeManager manager;
manager.addStudent(1001, "张三");
manager.addStudent(1002, "李四");
manager.addStudent(1003, "王五");
manager.addStudent(1004, "赵六");
manager.addScore(1001, "数学", 85);
manager.addScore(1001, "英语", 90);
manager.addScore(1001, "物理", 78);
manager.addScore(1002, "数学", 92);
manager.addScore(1002, "英语", 88);
manager.addScore(1002, "物理", 95);
manager.addScore(1003, "数学", 76);
manager.addScore(1003, "英语", 82);
manager.addScore(1003, "物理", 80);
manager.addScore(1004, "数学", 88);
manager.addScore(1004, "英语", 85);
manager.addScore(1004, "物理", 90);
manager.displayAll();
manager.sortByTotal();
manager.displayAll();
manager.findStudent(1002);
manager.getTopStudents(3);
return 0;
}小结
STL核心组件:
| 组件 | 说明 |
|---|---|
| 容器 | vector, list, map, set等 |
| 迭代器 | 遍历容器的统一接口 |
| 算法 | sort, find, transform等 |
| 函数对象 | lambda, function, bind |
智能指针:
| 类型 | 说明 |
|---|---|
| unique_ptr | 独占所有权 |
| shared_ptr | 共享所有权 |
| weak_ptr | 弱引用,避免循环引用 |