用步幅获取std::vector的最大元素

Get maximum element of std::vector with strides

本文关键字:元素 vector 获取 std      更新时间:2023-10-16

我有一个std::vector<float>,数据布局如下

x1 | y1 | z1 | x2 | y2 | z2 | .... | xn | yn | zn

我正试图找出一种类似STL的方法来获得最大x元素以及yz

明显的

double xyzmax = *std::max_element(myvector.begin(),myvector.end() );

选择绝对最大值,不允许我指定步幅。有没有一些没有for循环的技巧?

您可以使用Boost.Itererator库和Boost::Iterator_facade来创建一个跨步迭代器,它可以用std::vector<float>::iterator初始化,++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

相关文章: