::fast_io::vector
1. 什么是 vector?
::fast_io::vector<T> 存储一串 T 类型的元素。
当你添加更多元素时,它会自动增长,且所有元素都连续存放在同一块内存中。
你可以把它想象成一个“会增长的数值列表”,始终保持紧密排列。
2. 创建 vector
你可以创建空 vector,也可以创建带初始大小的 vector:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> a; // empty
::fast_io::vector<std::size_t> b(5zu); // 5 default-initialized elements
::fast_io::vector<std::size_t> c(3zu, 42zu); // 3 copies of value 42
println("b size = ", b.size());
println("c[0] = ", c[0]);
}
3. 添加元素
添加元素最常见的方式是 push_back():
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v;
v.push_back(10zu);
v.push_back(20zu);
v.push_back(30zu);
println("Size: ", v.size()); // 3
}
当 vector 空间用尽时,它会自动分配更多内存。
4. 安全地访问元素
你可以用 front()、back() 或 operator[] 访问元素:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{1zu, 2zu, 3zu, 4zu};
println("Front: ", v.front()); // 1
println("Back: ", v.back()); // 4
println("Index 2: ", v[2]); // 3
}
⚠️ 安全提示:如果你访问一个不存在的元素(例如在空 vector 上调用
v.front(),或使用越界索引),fast_io 会执行
边界检查。如果检查失败,程序会通过 __builtin_trap() 立刻停止。
安全用法
if(!v.is_empty()) {
println("Front: ", v.front());
}
std::size_t i = 2zu;
if(i < v.size()) {
println("v[2] = ", v[i]);
}
5. 遍历元素
首选:基于范围的 for 循环
这是遍历所有元素最简单的方式:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};
for(std::size_t x : v) {
println(x);
}
}
替代方案:索引循环
当你需要位置时很有用:
for(std::size_t i{}, n{v.size()}; i != n; ++i) {
println("Index ", i, ": ", v[i]);
}
进阶:迭代器
在第 3.1 节(字符串迭代器)中,我们介绍了迭代器的行为类似
指向容器内存的指针这一概念。::fast_io::vector<T> 使用与
::fast_io::string 相同的迭代器模型。
这意味着:
- 迭代器是连续的,并支持算术运算(
+/-、[]、比较) - 迭代使用左闭右开区间:
[begin(), end()) - 越出这个区间是未定义行为
- 如果 vector 重新分配(例如在已满时
push_back()),迭代器会失效
示例:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};
for(auto it = v.begin(), ed = v.end(); it != ed; ++it) {
println(*it);
}
}
迭代器算术
正如字符串一样,vector 的迭代器支持随机访问操作:
auto it = v.begin(); // first element
println(*(it + 1)); // move forward
println((it + 2)[0]); // same as v[2]
println((it + 2)[-1]); // move backward from a valid position
这些操作很快,但它们不做边界检查。
迭代器失效
任何导致 vector 增长的操作都可能重新分配其存储。 一旦发生这种情况,所有已有迭代器都会失效。
auto it2 = v.begin();
v.push_back(999zu); // may reallocate
// ⚠️ it2 may now point to old memory
// println(*it2); // undefined behavior
如果你需要在重新分配后保留位置,请保存索引而不是迭代器。
6. 删除元素
pop_back()
删除最后一个元素:
v.pop_back();
⚠️ 在空 vector 上调用 pop_back() 会让程序立刻停止。
7. 清空与释放内存
clear()
移除所有元素,但保留已分配的内存。 当你打算很快复用这个 vector 时很有用。
v.clear();
println(v.size()); // 0
clear_destroy()
移除所有元素,并把内存归还给分配器。 调用之后,vector 变成完全不占存储的空状态。
v.clear_destroy(); // memory returned to allocator
println(v.size()); // 0
当你用完 vector 并想释放它的内存时,使用 clear_destroy()。
要点
::fast_io::vector<T>存储一串不断增长、紧密排列的元素。push_back()添加新元素,并在需要时自动扩展存储。front()、back()与operator[]提供快速访问,但需要手工做边界检查。- vector 的迭代器行为与字符串迭代器完全一致:连续、支持算术运算,并使用
[begin(), end())。 clear()移除元素但保留内存;clear_destroy()移除元素并释放内存。