将矢量拆分为新的更小尺寸的矢量
Split vector into new smaller size vectors
问题
我有矢量 V = {1,2,3,4,5,6,7,8,9,10,11}
,假设我想从这个大矢量创建 N
新矢量。
示例:N = 3
表示它将按最大可用大小拆分向量,即 4-4-3
v1 = {1,2,3,4}
v2 = {5,6,7,8}
v3 = {9,10,11}
代码
std::vector<int> v;
for (int i = 1; i < 12; i++) v.push_back(i);
// Function here to set boundaries ???
N = 3;
v.size()/N % N
//
std::vector<int> v1(v.begin(), v.begin()+3);
std::vector<int> v2(v.begin()+4, v.begin()+7);
std::vector<int> v3(v.begin()+8, v.begin()+11);
想要实现
- 自动创建矢量的功能,所以我不想手动创建
v1,v2,v3
如果可能的话。
- 如何编写边界检查算法?
Function that does automatic creation of the vectors by itself so I don't want to manually create v1,v2,v3 if it is possible.
什么数据结构可以容纳 N 个对象?数组怎么样?但是您可能希望在运行时确定大小。您如何创建具有运行时大小的数组?使用矢量!总之,编写一个创建向量向量的函数。
请注意,与其使用单独的向量,不如保持原始向量完整并使用 std::span
的向量(在 C++20 之前,您可以使用非标准实现)可能更有效相同概念)指向子范围。
一个简单的方法是构建一个 vector
of vector
来收集不同的数组。
为了控制边界,一种可能是先计算这些数组的最大大小,
然后管理两个索引,一个 ibegin
对应子数组的开头,一个 iend
对应同一个子数组的结尾。
输出:
1 2 3 4
5 6 7 8
9 10 11
代码:
#include <iostream>
#include <vector>
std::vector<std::vector<int>> split (const std::vector<int>& v, int Nsplit) {
int n = v.size();
int size_max = n / Nsplit + (n % Nsplit != 0);
std::vector<std::vector<int>> split;
for (int ibegin = 0; ibegin < n; ibegin += size_max) {
int iend = ibegin + size_max;
if (iend > n) iend = n;
split.emplace_back (std::vector<int>(v.begin() + ibegin, v.begin() + iend));
}
return split;
}
int main() {
std::vector<int>Arr = {1,2,3,4,5,6,7,8,9,10,11};
int Nsplit = 3;
auto ans = split (Arr, Nsplit);
for (auto &v: ans) {
for (auto& i: v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
return 0;
}
如果你像这样分成 n
个块,你将得到 vec
的第 i 个块:
template <typename T>
std::span<T> get_chunk(std::vector<T> const & vec, std::size_t n, std::size_t i)
{
assert(i < n);
std::size_t const q = vec.size() / n;
std::size_t const r = vec.size() % n;
auto begin = vec.begin() + i * q + std::min(i, r);
auto end = vec.begin() + (i + 1) * q + std::min(i + 1, r);
return std::span<T>(begin, end);
}
如果你不会/不能使用std::span
,只需将其替换为std::vector
或直接使用begin
和end
迭代器即可。
问题
我有矢量 V = {1,2,3,4,5,6,7,8,9,10,11}
,假设我想从这个大矢量创建 N
新矢量。
示例:N = 3
表示它将按最大可用大小拆分向量,即 4-4-3
v1 = {1,2,3,4}
v2 = {5,6,7,8}
v3 = {9,10,11}
代码
std::vector<int> v;
for (int i = 1; i < 12; i++) v.push_back(i);
// Function here to set boundaries ???
N = 3;
v.size()/N % N
//
std::vector<int> v1(v.begin(), v.begin()+3);
std::vector<int> v2(v.begin()+4, v.begin()+7);
std::vector<int> v3(v.begin()+8, v.begin()+11);
想要实现
- 自动创建矢量的功能,所以我不想手动创建
v1,v2,v3
如果可能的话。 - 如何编写边界检查算法?
Function that does automatic creation of the vectors by itself so I don't want to manually create v1,v2,v3 if it is possible.
什么数据结构可以容纳 N 个对象?数组怎么样?但是您可能希望在运行时确定大小。您如何创建具有运行时大小的数组?使用矢量!总之,编写一个创建向量向量的函数。
请注意,与其使用单独的向量,不如保持原始向量完整并使用 std::span
的向量(在 C++20 之前,您可以使用非标准实现)可能更有效相同概念)指向子范围。
一个简单的方法是构建一个 vector
of vector
来收集不同的数组。
为了控制边界,一种可能是先计算这些数组的最大大小,
然后管理两个索引,一个 ibegin
对应子数组的开头,一个 iend
对应同一个子数组的结尾。
输出:
1 2 3 4
5 6 7 8
9 10 11
代码:
#include <iostream>
#include <vector>
std::vector<std::vector<int>> split (const std::vector<int>& v, int Nsplit) {
int n = v.size();
int size_max = n / Nsplit + (n % Nsplit != 0);
std::vector<std::vector<int>> split;
for (int ibegin = 0; ibegin < n; ibegin += size_max) {
int iend = ibegin + size_max;
if (iend > n) iend = n;
split.emplace_back (std::vector<int>(v.begin() + ibegin, v.begin() + iend));
}
return split;
}
int main() {
std::vector<int>Arr = {1,2,3,4,5,6,7,8,9,10,11};
int Nsplit = 3;
auto ans = split (Arr, Nsplit);
for (auto &v: ans) {
for (auto& i: v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
return 0;
}
如果你像这样分成 n
个块,你将得到 vec
的第 i 个块:
template <typename T>
std::span<T> get_chunk(std::vector<T> const & vec, std::size_t n, std::size_t i)
{
assert(i < n);
std::size_t const q = vec.size() / n;
std::size_t const r = vec.size() % n;
auto begin = vec.begin() + i * q + std::min(i, r);
auto end = vec.begin() + (i + 1) * q + std::min(i + 1, r);
return std::span<T>(begin, end);
}
如果你不会/不能使用std::span
,只需将其替换为std::vector
或直接使用begin
和end
迭代器即可。