std::advance
- [1. 函数原型](#1. 函数原型)
- [2. 功能](#2. 功能)
- [3. 返回值](#3. 返回值)
- [4. 适用范围](#4. 适用范围)
- [5. 工作原理](#5. 工作原理)
- [6. 性能](#6. 性能)
- [7. 示例代码](#7. 示例代码)
-
- [7.1. 正常使用 std::advance](#7.1. 正常使用 std::advance)
- [7.2. 使用 std::advance 来检查边界](#7.2. 使用 std::advance 来检查边界)
- [8. 特殊情况](#8. 特殊情况)
- [9. 总结](#9. 总结)
std::advance 是 C++ 标准库中的一个函数模板,定义在 头文件中。它用来移动一个迭代器,沿着容器的元素顺序前进或后退指定的步数。std::advance 是一个通用的迭代器操作,可以作用于任何支持前向(Forward Iterator)、双向(Bidirectional Iterator)或随机访问(Random Access Iterator)特性的迭代器。
1. 函数原型
cpp
template <typename InputIterator, typename Distance>
void advance(InputIterator& it, Distance n);
- InputIterator& it:要移动的迭代器。
- Distance n:要移动的步数。可以是正数(向前移动)或负数(向后移动)。
2. 功能
std::advance 会根据指定的步数(n)来改变迭代器的位置:
- 如果 n > 0,则迭代器会向容器的后方(即下一个元素)移动。
- 如果 n < 0,则迭代器会向容器的前方(即上一个元素)移动。
- 如果 n == 0,迭代器保持不动。
3. 返回值
std::advance 是一个 void 函数,它不会返回任何值。它会直接修改传入的迭代器 it。
4. 适用范围
std::advance 可用于不同类型的迭代器:
- 前向迭代器(Forward Iterator):支持单向前进。
- 双向迭代器(Bidirectional Iterator):支持前进和后退。
- 随机访问迭代器(Random Access Iterator):支持直接的偏移量操作,允许 O(1) 时间复杂度的步进。
5. 工作原理
- 对于 前向迭代器,std::advance 会调用 operator++ 或 operator-- 来逐步移动迭代器。
- 对于 双向迭代器,它可以调用 operator++ 和 operator-- 来向前或向后移动。
- 对于 随机访问迭代器,std::advance 可以直接通过加法和减法操作来移动迭代器(例如 it += n 或 it -= n),这样可以更高效地移动迭代器。
6. 性能
- 随机访问迭代器:std::advance 对于随机访问迭代器是 O(1) 的,因为可以通过直接的加法或减法来修改迭代器的位置。
- 双向迭代器:std::advance 对于双向迭代器是 O(n) 的,n 是步数,因为必须逐步调用 ++ 或 --。
- 前向迭代器:std::advance 对于前向迭代器的复杂度也是 O(n),因为每次只能前进一个元素。
7. 示例代码
7.1. 正常使用 std::advance
cpp
#include <iostream>
#include <vector>
#include <iterator> // std::advance
int main() {
std::vector<int> vec = {10, 20, 30, 40, 50};
// 获取迭代器
auto it = vec.begin();
// 正向移动2步
std::advance(it, 2);
std::cout << "After advancing 2 steps: " << *it << std::endl; // 输出: 30
// 负向移动1步
std::advance(it, -1);
std::cout << "After retreating 1 step: " << *it << std::endl; // 输出: 20
return 0;
}
输出:
yaml
After advancing 2 steps: 30
After retreating 1 step: 20
7.2. 使用 std::advance 来检查边界
在使用 std::advance 时,如果步数过大或过小,可能会导致迭代器越界,因此在调用之前通常需要检查容器的边界。
cpp
#include <iostream>
#include <vector>
#include <iterator> // std::advance
int main() {
std::vector<int> vec = {10, 20, 30, 40, 50};
auto it = vec.begin();
// 移动到最后
std::advance(it, 4); // 正向移动到 50
std::cout << "Last element: " << *it << std::endl; // 输出: 50
// 超出范围的移动
if (it != vec.end()) {
std::advance(it, 1); // 越界操作
}
if (it == vec.end()) {
std::cout << "Iterator out of range!" << std::endl;
}
return 0;
}
8. 特殊情况
对于随机访问迭代器:std::advance 是常数时间复杂度的,因为可以直接通过偏移量移动迭代器。
cpp
std::advance(it, 3); // 如果 it 是一个随机访问迭代器,直接偏移3个位置
对于双向迭代器或前向迭代器:std::advance 需要逐步调用 ++ 或 -- 来向前或向后移动迭代器,因此其时间复杂度是 O(n),其中 n 是步数。
9. 总结
- std::advance 是一个灵活的迭代器操作函数,可以方便地移动迭代器,不需要手动编写复杂的循环代码来实现迭代器的前进或后退。
- 它可以处理正向移动、负向移动、以及随机访问和双向迭代器的移动,具有广泛的适用性。
- 对于 随机访问迭代器,std::advance 提供了非常高效的偏移操作,而对于 双向或前向迭代器,则是逐步移动,效率相对较低。