与std :: minmax_element一起使用的Step/Stride Iterator [英] Step/Stride Iterator for use with std::minmax_element
问题描述
我有一个一维浮点数组,它表示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 ?
推荐答案
使用两种方法(其中有很多)正在使用 boost :: range
)和
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;
}
在 请注意以下几点: 一个范围可以由一对迭代器定义,因此我在这里使用了它,尽管可以采用一种更简单的形式(它适合您使用堆分配的C样式数组的用例). 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. 考虑到随机访问迭代器,构建跨步向前 对于 This should be enough for 这篇关于与std :: minmax_element一起使用的Step/Stride Iterator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! boost :: range
中,使用
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
成员,并更改标签,也会使它成为随机访问迭代器.)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;
}