加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 用于std :: minmax_element的Step / Stride Iterator

发布时间:2020-12-16 10:04:05 所属栏目:百科 来源:网络整理
导读:我有一个1D浮点数组,表示浮点值的m * n(行和列)表.我的要求是为每行和每列找到最小/最大元素.对于行,我可以通过指定n个元素的范围使用std :: minmax_element来轻松完成.但是对于列我需要使用步长迭代器,因为放置的元素不是连续的,而是以n的步长间隔放置.是否
我有一个1D浮点数组,表示浮点值的m * n(行和列)表.我的要求是为每行和每列找到最小/最大元素.对于行,我可以通过指定n个元素的范围使用std :: minmax_element来轻松完成.但是对于列我需要使用步长迭代器,因为放置的元素不是连续的,而是以n的步长间隔放置.是否可以使用boost / STL中的标准迭代器.另一种选择是编写我自己的版本.
什么是最好的课程?

解决方法

两种方式(多种方式)使用 range-v3(或 boost::range)和 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中,使用boost::adaptors::strided.

#include <boost/range/adaptor/strided.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <boost/assign.hpp>
#include <boost/range/algorithm.hpp>
#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    using namespace boost::adaptors;
    using namespace boost::assign;

    std::vector<int> input;
    int arr[] = {1,7};

    auto str = std::make_pair(&arr[0],&arr[8]) | strided(3);
    std::cout << *boost::range::min_element(str) << " " << *boost::range::max_element(str) << std::endl;
}

请注意以下事项:

>一个范围可以由一对迭代器定义,所以我在这里使用了它,虽然可以使用更简单的形式(它适合堆分配的C风格数组的用例).
>不幸的是,这个子库似乎没有min-max(或者至少我找不到它),所以有两个调用,一个用于min,一个用于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来说这应该足够了. (添加一些逻辑,减量和高级成员,以及更改标记,也会使它成为随机访问迭代器.)

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读