我有一个来源 std::vector<double>
,我想根据 std::vector<int>
中包含的索引进行拆分.分割是包容性的,下一个切片的开始应该从前一个停止的地方开始,从源 vector 的开始开始。
例如:
{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 } -> source
{2, 4, 7 } -> split indices
在应用函数后它应该产生:
{1.1, 2.2, 3.3}
{4.4, 5.5}
{6.6, 7.7, 8.8}
我有这个不会给我第三个 vector 等等:
vector<double> nets{ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9 };
vector<int> ends{2, 4, 7 };
vector<vector<double>> periodnumbers;
vector<double> numbers;
for (int i = 0; i < nets.size(); i++)
{
double temp;
temp = nets[i];
numbers.push_back(temp);
for (int j = 0; j < ends.size(); j++)
{
if (i == ends[j])
{
periodnumbers.push_back(numbers);
numbers.clear();
}
}
}
最佳答案
糟糕的算法
即使它起作用了,它也做了太多不必要的操作。从遍历所有元素开始,以 push_back
ing 结束,而不是保留/调整大小。
更好的算法
假设 ends
已排序。然后一个人可以只拿两个“ slider ”,并继续移动它们。左边的 slider 从源 vector 的起点开始,右边的 slider 从第一端开始。随着算法的进行,它会复制 slider 内的当前范围,将左 slider 移动到右 slider ,右 slider 成为下一个末端。
#include <vector>
#include <algorithm>
std::vector<std::vector<double>> split_ends(const std::vector<double>& source, const std::vector<int>& ends) {
std::vector<std::vector<double>> result;
result.reserve(ends.size());
auto anchor_front = source.begin();
for (auto one_end: ends) {
auto anchor_end = std::next(source.begin(), one_end + 1);
result.emplace_back(anchor_front, anchor_end);
anchor_front = anchor_end;
}
return result;
}
#include <iostream>
void print(const std::vector<double>& v)
{
for (auto x: v) {
std::cout << x << ' ';
}
}
int main() {
std::vector<double> nets{1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9};
std::vector<int> ends{2, 4, 7};
auto splitted = split_ends(nets, ends);
for (const auto& v: splitted) {
print(v);
std::cout << '\n';
}
}
输出:
1.1 2.2 3.3
4.4 5.5
6.6 7.7 8.8
上述算法假定 ends
已排序且不包含超出范围的索引。如果不需要拷贝,可以只保存端点迭代器,并直接对源执行更改。
关于c++ - 如何根据另一个 vector 中给出的索引拆分 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51090810/