迭代器是用于访问容器元素的对象,类似于指针
begin()和end()方法:
vector<int> vec = {10, 20, 30, 40, 50};
// begin() - 返回指向第一个元素的迭代器
auto it_begin = vec.begin();
cout << *it_begin << endl; // 10
// 可以通过迭代器修改元素
*it_begin = 100; // 现在vec是 {100, 20, 30, 40, 50}
// end() - 返回指向末尾后一个位置的迭代器(不指向实际元素)
auto it_end = vec.end();
// 注意:不能直接解引用end()迭代器,因为它指向末尾之后的位置
// 使用迭代器访问特定位置
auto third = vec.begin() + 2; // 指向第三个元素
cout << *third << endl; // 30
迭代器的使用方式:
vector<int> vec = {10, 20, 30, 40, 50};
// 使用迭代器遍历
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " "; // 10 20 30 40 50
}
// 使用auto简化(C++11)
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " "; // 10 20 30 40 50
}
// 使用范围for循环(C++11)
for (int val : vec) {
cout << val << " "; // 10 20 30 40 50
}
// 反向迭代器
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
cout << *it << " "; // 50 40 30 20 10
}
vector如何管理内存:
vector<int> vec;
cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << endl;
for (int i = 0; i < 10; i++) {
vec.push_back(i);
cout << "Size: " << vec.size() << ", Capacity: " << vec.capacity() << endl;
}
// 输出可能类似于:
// Size: 0, Capacity: 0
// Size: 1, Capacity: 1
// Size: 2, Capacity: 2
// Size: 3, Capacity: 4
// Size: 4, Capacity: 4
// Size: 5, Capacity: 8
// ...
为什么预分配内存:
reserve vs resize:
reserve:仅分配内存,不创建元素resize:调整大小并创建元素// 不预分配
vector<int> v1;
for (int i = 0; i < 10000; i++) {
v1.push_back(i); // 可能多次重新分配
}
// 预分配
vector<int> v2;
v2.reserve(10000); // 一次性分配足够空间
for (int i = 0; i < 10000; i++) {
v2.push_back(i); // 不会重新分配
}
// 使用resize
vector<int> v3;
v3.resize(10000); // 创建10000个值为0的元素
for (int i = 0; i < 10000; i++) {
v3[i] = i; // 直接赋值,不使用push_back
}
vector可以存储任何类型的元素,包括结构体。
// 定义一个学生结构体
struct Student {
string name;
int age;
double score;
// 构造函数
Student(string n, int a, double s) :
name(n), age(a), score(s) {}
// 显示学生信息
void display() const {
cout << "Name: " << name
<< ", Age: " << age
<< ", Score: " << score << endl;
}
};
int main() {
// 创建Student结构体的vector
vector<Student> students;
// 添加学生
students.push_back(Student("Alice", 15, 92.5));
students.push_back(Student("Bob", 16, 85.0));
students.push_back(Student("Charlie", 15, 97.5));
// 遍历并显示所有学生
for (const auto& student : students) {
student.display();
}
// 直接访问结构体成员
cout << "第一名学生: " << students[0].name
<< ", 分数: " << students[0].score << endl;
return 0;
}
二维vector:
// 创建5x4的二维vector
vector<vector<int>> matrix(5, vector<int>(4, 0));
// 访问和修改元素
matrix[2][3] = 10;
// 获取行数和列数
int rows = matrix.size();
int cols = matrix[0].size();
// 遍历二维vector
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
不规则二维vector:
// 创建行数不固定的二维vector
vector<vector<int>> irregular;
// 添加不同长度的行
irregular.push_back({1, 2, 3});
irregular.push_back({4, 5});
irregular.push_back({6, 7, 8, 9});
// 遍历不规则二维vector
for (const auto& row : irregular) {
for (int val : row) {
cout << val << " ";
}
cout << endl;
}
// 输出:
// 1 2 3
// 4 5
// 6 7 8 9
三维及更高维:
// 三维vector (2x3x4)
vector<vector<vector<int>>> cube(2,vector<vector<int>>(3, vector<int>(4, 0)));
C++标准库提供了许多可以与vector一起使用的算法,需要包含<algorithm>头文件
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
sort(vec.begin(), vec.end()); // 排序 {1, 2, 3, 4, 5, 6, 7, 8, 9}
sort(vec.begin(), vec.end(), greater<int>()); //反向排序 {9, 8, 7, 6, 5, 4, 3, 2, 1}
auto it = find(vec.begin(), vec.end(), 7); // 查找元素
if (it != vec.end()) {
cout << "Found 7 at position: " << (it - vec.begin()) << endl;
}
int count = count(vec.begin(), vec.end(), 5); // 计算元素出现次数
auto minmax = minmax_element(vec.begin(), vec.end()); // 最大值和最小值
cout << "Min: " << *minmax.first << ", Max: " << *minmax.second << endl;
return 0;
}
使用比较函数:
// 自定义比较函数
bool compareByAbsValue(int a, int b) {
return abs(a) < abs(b);
}
int main() {
vector<int> vec = {-5, 3, -2, 8, -1, 0, 4};
// 按绝对值排序
sort(vec.begin(), vec.end(), compareByAbsValue);
// {0, -1, -2, 3, 4, -5, 8}
return 0;
}
使用lambda表达式(C++11):
vector<int> vec = {-5, 3, -2, 8, -1, 0, 4};
// 使用lambda表达式按绝对值排序
sort(vec.begin(), vec.end(),
[](int a, int b) {
return abs(a) < abs(b);
}
);// {0, -1, -2, 3, 4, -5, 8}
排序自定义类型:
// 按学生成绩排序
sort(students.begin(), students.end(),
[](const Student& a, const Student& b) {
return a.score > b.score; // 直接访问公开成员
}
);
vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5};
vector<int> vec2(5);
reverse(vec.begin(), vec.end()); //反转 {5, 6, 2, 9, 5, 1, 4, 1, 3}
random_shuffle(vec.begin(), vec.end());// 随机打乱
sort(vec.begin(), vec.end());
auto last = unique(vec.begin(), vec.end());// 去除重复元素(需要先排序)
vec.erase(last, vec.end()); // {1, 2, 3, 4, 5, 6, 9}
copy(vec.begin(), vec.begin() + 5, vec2.begin());// 复制元素
fill(vec2.begin(), vec2.end(), 10); // 填充元素所有元素设为10
vector<int> seq(10);
iota(seq.begin(), seq.end(), 1); //生成序列 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
int sum = accumulate(vec.begin(), vec.end(), 0);// 累加
vector<int> partialSums(vec.size());
partial_sum(vec.begin(), vec.end(), partialSums.begin());// 部分和
题目说明:
问题分析:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
// 存储所有区间
vector<pair<int, int>> intervals;
// 读取区间
for (int i = 0; i < n; i++) {
int start, end;
cin >> start >> end;
intervals.push_back({start, end});
}
// 按区间起点排序
sort(intervals.begin(), intervals.end());
// 合并重叠区间
vector<pair<int, int>> merged;
merged.push_back(intervals[0]);
for (int i = 1; i < n; i++) {
// 如果当前区间的起点小于等于上一个合并区间的终点,则合并
if (intervals[i].first <= merged.back().second) {
merged.back().second = max(merged.back().second, intervals[i].second);
} else {
// 否则添加新区间
merged.push_back(intervals[i]);
}
}
// 输出结果
cout << "合并后的区间数量: " << merged.size() << endl;
for (const auto& interval : merged) {
cout << "[" << interval.first << ", " << interval.second << "] ";
}
cout << endl;
return 0;
}
题目说明:
问题分析:
#include <iostream>
#include <vector>
#include <deque>
using namespace std;
vector<int> maxSlidingWindow(const vector<int>& nums, int k) {
vector<int> result;
deque<int> dq; // 存储元素的索引
for (int i = 0; i < nums.size(); i++) {
// 移除不在当前窗口的元素
while (!dq.empty() && dq.front() < i - k + 1) {
dq.pop_front();
}
// 移除所有小于当前元素的值
while (!dq.empty() && nums[dq.back()] < nums[i]) {
dq.pop_back();
}
// 添加当前元素的索引
dq.push_back(i);
// 当窗口形成后,记录最大值
if (i >= k - 1) {
result.push_back(nums[dq.front()]);
}
}
return result;
}
int main() {
int n, k;
cin >> n >> k;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
vector<int> result = maxSlidingWindow(nums, k);
cout << "滑动窗口最大值: ";
for (int val : result) {
cout << val << " ";
}
cout << endl;
return 0;
}
题目说明:
问题分析:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int lengthOfLIS(const vector<int>& nums) {
if (nums.empty()) return 0;
// tails[i]表示长度为i+1的上升子序列的最小结尾值
vector<int> tails;
for (int num : nums) {
// 使用二分查找找到第一个大于等于num的位置
auto it = lower_bound(tails.begin(), tails.end(), num);
if (it == tails.end()) {
// 如果所有值都小于num,添加到末尾
tails.push_back(num);
} else {
// 否则更新该位置的值
*it = num;
}
}
return tails.size();
}
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
int result = lengthOfLIS(nums);
cout << "最长上升子序列的长度: " << result << endl;
return 0;
}
成绩统计:
数字反转:
简单排序:
删除重复元素:
区间查询:
滑动窗口最小值:
1. 学生成绩管理系统:
2. 通讯录管理:
3. 矩阵运算:
4. 图像处理:
USACO:
Livestock Lineup (★★☆☆☆)
Why Did the Cow Cross the Road (★★★☆☆)
POJ/HDU:
POJ 3069 - Saruman's Army (★★☆☆☆)
HDU 1232 - 畅通工程 (★★☆☆☆)
3. 矩阵计算器
4. 图像处理
USACO:
POJ:
HDU:


感谢学习!
如有疑问,请联系:
judal@xmaker.org
魅客科创中心
这个讲义使用了Awesome Marp主题的蓝色风格。 内容针对中小学生设计,使用简单易懂的语言和示例。 假设学生已经了解普通数组的使用。