簡體   English   中英

用於std :: minmax_element的Step / Stride Iterator

[英]Step/Stride Iterator for use with std::minmax_element

我有一個浮點數組,表示浮點值的am * 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, 2, 3, 4, 5, 6, 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;
}

請注意以下事項:

  1. 范圍可以由一對迭代器定義,所以我在這里使用了它,雖然可以使用更簡單的形式(它適合堆分配的C風格數組的用例)。

  2. 不幸的是,這個子庫似乎沒有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這應該足夠了。 (添加一些邏輯, decrementadvance成員,以及更改標記,也會使它成為隨機訪問迭代器。)

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM