与std :: minmax_element一起使用的Step/Stride Iterator [英] Step/Stride Iterator for use with std::minmax_element

查看:58
本文介绍了与std :: minmax_element一起使用的Step/Stride Iterator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个一维浮点数组,它表示m * n(行和列)浮点值表.我的要求是为每一行和每一列找到一个最小/最大元素.对于行,我可以通过指定n个元素的范围来使用std :: minmax_element轻松实现.但是对于列,我需要使用跨步迭代器,因为元素的放置位置不是连续的,而是以n的步长间隔放置.在boost/STL中是否有可以使用的标准迭代器.另一个选择是编写自己的版本.最好的课程是什么?

I have a 1D float array which represents a m *n (rows and columns) table of float values. My requirement is to find a min/max element for each row and column. For rows I can easily do it by using std::minmax_element by specifying a range of n elements. But for columns I need to use a stride iterator as elements are placed are not contiguous but placed at a step interval of n. Is there a standard iterator in boost/STL that can be used. The other option is to write my own version of it. What is the best course ?

推荐答案

使用两种方法(其中有很多)正在使用

Two ways (among many) of doing it are using range-v3 (or boost::range) and boost::iterator.

使用 range-v3 ,它立即生效:

#include <iostream>
#include <range/v3/all.hpp>

using namespace ranges;

int main() {
    std::vector<std::size_t> src{1, 2, 3, 4, 5, 6, 7};
    const auto min_max = minmax(src | view::stride(3));
    std::cout << min_max.first << " " << min_max.second << std::endl;
}


boost :: range 中,使用

请注意以下几点:

  1. 一个范围可以由一对迭代器定义,因此我在这里使用了它,尽管可以采用一种更简单的形式(它适合您使用堆分配的C样式数组的用例).

  1. A range can be defined by a pair of iterators, so I used that here although a simpler form is possible (it fits your use case of heap-allocated C-style arrays).

不幸的是,该子库似乎没有min-max(或者至少我找不到它),因此有两个调用,一个用于min,一个用于max.

Unfortunately, this sub-library doesn't seem to have min-max (or at least I couldn't find it), so there are two calls, one for min, and one for max.


考虑到随机访问迭代器,构建跨步向前 boost :: iterator_facade :

#include <iostream>
#include <vector>
#include <iterator>
#include <cstddef>
#include <algorithm>
#include <boost/iterator/iterator_facade.hpp>

template<typename It>
class stride_iterator :
    public boost::iterator_facade<
        stride_iterator<It>,
        typename std::iterator_traits<It>::value_type,
        boost::forward_traversal_tag> {
public:
    stride_iterator() = default;
    stride_iterator(It it, It end_it, std::size_t stride) : 
        m_it{it}, m_end_it{end_it}, m_stride{stride} 
    {}

private:
    friend class boost::iterator_core_access;

    void increment() { 
        if(std::distance(m_it, m_end_it) < m_stride) {
            m_it = m_end_it;
            return;
        }
        std::advance(m_it, m_stride);
    }

    bool equal(const stride_iterator<It> &other) const {
        return m_it == other.m_it;
    }

    typename std::iterator_traits<It>::value_type &dereference() const { 
        return *m_it; }

    It m_it, m_end_it;
    std::size_t m_stride;
};

对于 std :: minmax_element 这应该足够了.(添加一些逻辑, decrement advance 成员,并更改标签,也会使它成为随机访问迭代器.)

This should be enough for std::minmax_element. (Adding a bit of logic, the decrement and advance members, and changing the tag, would make it into a random-access iterator too.)

int main() {
    using vec_t = std::vector<int>;
    vec_t v{1, 2, 3, 4, 5, 6, 7};
    stride_iterator<vec_t::iterator> b{std::begin(v), std::end(v), 3}, e{std::end(v), std::end(v), 3};
    auto min_max = std::minmax_element(b, e);
    std::cout << *min_max.first << " " << *min_max.second << std::endl;
}

这篇关于与std :: minmax_element一起使用的Step/Stride Iterator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆