在C++中切片一个向量
在C++中切片一个向量的问题的出现是因为需要确定是要一个视图(view)还是一个副本(copy)。
Python中对于列表的切片会复制元素的引用,因此不能简单地将其视为视图或副本。例如:
list1 = [1, 2, 3] list2 = list1[1:] list2[1] = 5 print(list1) # 输出不变,仍然是[1, 2, 3]
list1 = [1, 2, [3]] list2 = list1[1:] list2[1][0] = 5 print(list1) # 输出改变,变成[1, 2, [5]]
详情请参考[这个帖子](https://stackoverflow.com/a/5131563/5376789)。
[DimChtz的回答](https://stackoverflow.com/a/50549636/5376789)模拟了复制的情况。如果你只想要一个视图,在C++20中,你可以使用[ranges](https://en.cppreference.com/w/cpp/ranges)(除了[std::views::drop](https://en.cppreference.com/w/cpp/ranges/drop_view)、[std::views::take](https://en.cppreference.com/w/cpp/ranges/take_view)和[std::views::counted](https://en.cppreference.com/w/cpp/ranges/view_counted)之外):
auto v2 = v1 | std::views::drop(1); // 需要包含for (auto &e: v2) std::cout << e << '\n';
或者使用[std::span](https://en.cppreference.com/w/cpp/container/span):
std::span v2{v1.begin() + 1, v1.end()}; // 需要包含
for (auto &e: v2) std::cout << e << '\n';
还可以使用带有span的`std::span::subspan()`方法。不过它不支持负索引。
C++20中提供了一种简单的方法来切片向量(Slicing a vector)。上述代码使用了C++20的新特性,展示了如何使用切片语法对向量进行切片操作。
切片函数的代码如下所示:
#include
#include
#include
template
constexpr auto slice(T&& container)
{
if constexpr (right > 0)
{
return std::span(begin(std::forward(container))+left, begin(std::forward(container))+right);
}
else
{
return std::span(begin(std::forward(container))+left, end(std::forward(container))+right);
}
}
在主函数中,通过调用切片函数对向量进行切片操作,并输出结果。
通过运行上述代码,可以得到以下结果:
------------------- 2 3 4 5 6 7 8 9 ------------------- 1 2 3 4 5 6 7 8 ------------------- 2 3 ------------------- 2 3 4 5 6 7 8 -------------------
上述代码展示了如何使用切片语法对向量进行切片操作,通过指定左边界和右边界来选择切片的范围。切片函数支持正向和反向索引,可以灵活地对向量进行切片。
这种切片语法非常酷,但为什么不使用`std::slice`呢?
`std::slice`也可以实现切片操作,但我想尝试一种类似Python中对`std::vector`使用切片语法的方式。据我了解,`std::slice`不适用于`std::vector`。
总之,通过使用C++20的新特性,我们可以很方便地对向量进行切片操作,提供了一种更简洁和直观的语法来处理向量的子集。
Slicing a vector in C++
在C++中切片一个向量是非常简单的,可以使用std::vector
的拷贝构造函数来完成。代码如下:
v2 = std::vector<int>(v1.begin() + 1, v1.end());
然而,这个答案还可以改进,需要明确是否包含v1.end()
这个元素。于是有人提出了问题:v2中是否包含v1中的最后一个元素?
答案是肯定的,v2中确实包含v1的最后一个元素。否则,答案就是错误的,因为提问者要求的是从向量中获取除第一个元素之外的所有元素。
还有一个人提到了要把这个信息加入到答案中,以使其更加完整。
需要说明的是,v1.end()
并不指向向量的最后一个元素,而是指向最后一个元素之后(不存在的)一个元素的迭代器。
时间复杂度是O(size of sliced vector)
。
请移除最后一句话,正如前面所提到的,v1.end()
并不指向向量的最后一个元素,因此v2中不包含v1.end()。