我有std::vector<float>
以下数据布局
x1 | y1 | z1 | x2 | y2 | z2 | .... | xn | yn | zn
我正在尝试找出一种 STL 式的方法来获得最大x
元素以及y
或z
显而易见的
double xyzmax = *std::max_element(myvector.begin(),myvector.end() );
选择绝对最大值,不允许我指定步幅。有没有没有for循环的技巧?
您可以使用Boost.Iterator库和boost::iterator_facade来创建一个跨步迭代器,该迭代器可以用 astd::vector<float>::iterator
和 for which在底层迭代器上进行初始化++it
。it += 3;
给定这样一个类型的迭代器StrideIt
,你可以写
maxX = *std::max_element(StrideIt(v.begin() + 0), StrideIt(v.end() - 2));
maxY = *std::max_element(StrideIt(v.begin() + 1), StrideIt(v.end() - 1));
maxZ = *std::max_element(StrideIt(v.begin() + 2), StrideIt(v.end() - 0));
这最好是重新定义算法,因为算法比迭代器类型多得多。
如果您想要最大的灵活性,您可以制作StrideIt
一个类模板,采用类型(float
在您的情况下)和定义步幅的运行时构造器参数(在您的情况下为 3)。
这是一个参考实现std::max_element
。
template<class ForwardIt>
ForwardIt max_element(ForwardIt first, ForwardIt last)
{
if (first == last) {
return last;
}
ForwardIt largest = first;
++first;
for (; first != last; ++first) {
if (*largest < *first) {
largest = first;
}
}
return largest;
}
您可以通过以下方式修改它来创建自己的算法:
template<class ForwardIt>
ForwardIt max_element_nth(ForwardIt first, ForwardIt last, int n)
{
if (first == last) {
return last;
}
ForwardIt largest = first;
first += n;
for (; first < last; first += n) {
if (*largest < *first) {
largest = first;
}
}
return largest;
}
当然,它有只能使用随机访问迭代器的限制,但它确实适用于vector
.
double xmax = *max_element_nth(myvector.begin(),myvector.end(), 3);
double ymax = *max_element_nth(myvector.begin()+1,myvector.end(), 3);
double zmax = *max_element_nth(myvector.begin()+2,myvector.end(), 3);
但我宁愿通过将 (x, y, z) 值存储在一个结构中来做到这一点,并取一个向量。然后,您可以将标准max_element
与自定义比较器一起使用。