[英]Can I use std::minmax_element in a member initializer list?
[英]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;
}
請注意以下事項:
范圍可以由一對迭代器定義,所以我在這里使用了它,雖然可以使用更簡單的形式(它適合堆分配的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
這應該足夠了。 (添加一些邏輯, decrement
和advance
成員,以及更改標記,也會使它成為隨機訪問迭代器。)
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.