使用strides获取std :: vector的最大元素

时间:2013-07-17 09:52:56

标签: c++ algorithm stl max stride

我有一个std::vector<float>,其中包含以下数据布局

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

我正试图找出一种STL-ish方法来获取最大x元素以及yz

显而易见的

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

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

2 个答案:

答案 0 :(得分:3)

您可以使用Boost.Iterator库和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类模板采用类型(在您的情况下为{{1}})和运行时construtor参数来定义步幅(在您的情况下为3)。

答案 1 :(得分:1)

以下是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与自定义比较器一起使用。