我想提取一个填充了结构的向量的子集,并形成一个新的向量,该向量只填充该子集的一个成员变量。
主矢量用这样的结构填充:
struct ImageParams{
double startTime;
double stopTime;
std::string path;
std::string activeInstrument;
bool projected;
};
所以说我的申请已经从t0跳过了 - > t1,然后我想要在t0和t之间的每个startTime
。 T1。我目前使用二进制查找操作遍历主向量,并将每个startTime
存储在一个新的返回向量中,如下所示:
captureTime = t1;
while (captureTime > t0){
auto binary_find = [](std::vector<ImageParams>::iterator begin,
std::vector<ImageParams>::iterator end,
const ImageParams &val,
bool(*cmp)(const ImageParams &a, const ImageParams &b))->std::vector<ImageParams>::iterator{
std::vector<ImageParams>::iterator it = std::lower_bound(begin, end, val, cmp);
if (it != begin){
return std::prev(it);
}
return end;
};
// Finds the lower bound in at most log(last - first) + 1 comparisons
auto it = binary_find(mainVec.begin(), mainVec.end(),
{ captureTime, 0, "", "", false }, cmp);
if (it == mainVec.end()) return false;
if (it->startTime < t0) break;
returnVec.push_back(it->startTime);
captureTime = it->startTime - 1;
}
我想要实现的目标:
这有效,但我认为它与while循环看起来很难看。我想也许有一种有效的方法(如果在mainVec
中找到一个匹配时间t0和t1的两个iter-position),就形成一个只有startTime
成员变量的新向量。
我想象这样的事情,
std::vector<double> returnVec = std::vector(mainVec.begin () + first,
mainVec.begin () + last);
但可以说“只提取startTime
成员变量”
也许我会过度思考它?
答案 0 :(得分:2)
以下是使用std::transform
的示例:
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
#include <iostream>
struct ImageParams {
double startTime;
double stopTime;
std::string path;
std::string activeInstrument;
bool projected;
};
int main()
{
// Our initial vector of ImageParams
const std::vector<ImageParams> vec {
{ 1.0, 0.0, std::string(), std::string(), false },
{ 2.0, 0.0, std::string(), std::string(), false },
{ 3.0, 0.0, std::string(), std::string(), false },
{ 4.0, 0.0, std::string(), std::string(), false }
};
// A subset of our initial vector's startTimes
std::vector<double> subset;
std::transform(vec.begin() + 1, vec.end(),
std::back_inserter(subset),
[](const ImageParams& i) { return i.startTime; });
// Print the subset
std::cout << "subset contains: ";
for (double d : subset) {
std::cout << d << ' ';
}
return 0;
}
输出:
subset contains: 2 3 4
在最简单的形式中,std::transform
接受一系列元素(通过第一个和最后一个迭代器),一个目标迭代器(这里我们使用std::back_inserter
将转换函数的结果插入到子集向量中),我们传递一个lambda函数来提取每个ImageParams
元素的开始时间。
答案 1 :(得分:1)
(完全重复我的回答以回复评论 - 你可以在编辑历史中看到原文。)
如果您使用的是C ++ 11,则可以使用std::transform
和仿函数或lambda执行此操作:
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
struct ImageParams
{
double startTime;
double stopTime;
std::string path;
std::string activeInstrument;
bool projected;
};
struct ExtractStartTime
{
double operator()(const ImageParams& params) const
{
return params.startTime;
}
};
int main()
{
ImageParams params = { 1.0, 0.0, std::string(), std::string(), false };
std::vector<ImageParams> big_vec(5, params);
big_vec[4].startTime = 5.0;
std::vector<double> small_vec;
std::transform(big_vec.begin() + 2, big_vec.end(), std::back_inserter(small_vec), ExtractStartTime());
for(int i = 0; i < small_vec.size(); ++i)
{
std::cout << "[" << i << "]: " << small_vec[i] << std::endl;
}
}