c++ max_element 每 n 个元素
c++ max_element every n element
有没有办法通过比较每 N 个元素和 return 索引来找到容器中的最大元素。使用 STL、BOOST 或...另一个库?
对于每个 N,我的意思是使用 std::max_element,但将 for 的增量从 ++first 更改为 first += n;
// based on std::max_element
#ifndef NEWTON_ALGORITHM_SEARCH_MAX_INDEX_HPP
#define NEWTON_ALGORITHM_SEARCH_MAX_INDEX_HPP
#include <iterator>
#include <newton/functional.hpp>
namespace newton {
// SAME THAT STD::MAX_ELEMENT
template<class ForwardIt, class Compare>
const ForwardIt max_index(ForwardIt first, ForwardIt last, Compare comp)
{
if ( newton::equal(first, last) ) // newton::equal is basically equivalent to std::equal_to
return last;
ForwardIt largest = first;
while ( newton::not_equal(++first, last) )
if (comp(*largest, *first))
largest = first;
return largest;
}
// possible names
// max_index_some
// max_index_every_n
// max_index__n
template<class ForwardIt, class Size, class Compare>
const ForwardIt max_index_every_n(ForwardIt first, ForwardIt last, Size n, Compare comp)
{
if ( newton::equal(first, last) )
return last;
ForwardIt largest = first;
Size blocks = std::distance(first, last) / n; // integer blocks
if ( newton::greater_equal(blocks, 1) ) {
// if there are exacly N elements, can't sum example
// v.size() = 10, first start in 0, so "0 += 10" is "10", but last index is "9"
// but if mod >= 1, then index is at least 10, so can sum
if ( newton::greater_equal( std::distance(first, last) % n, 1) ) {
for (size_t i = 1; newton::less_equal(i, blocks); ++i, first += n) {
if (comp(*largest, *first))
largest = first;
}
}
else {
for (size_t i = 1; newton::less(i, blocks); ++i, first += n) {
if (comp(*largest, *first))
largest = first;
}
}
}
return largest;
}
template<class ForwardIt>
const ForwardIt max_index(ForwardIt first, ForwardIt last)
{
return max_index(first, last, newton::structure::less());
}
} // newton
如果没有,您尝试将其包含在下一个 STL 版本中的解决方案是什么。 remember
对于 range-v3,它将是:
auto r = v | ranges::view::stride(n);
auto it = ranges::max_element(r);
仅使用 Boost("Range V2" 可以这么说):
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(100);
boost::iota(v, 0);
int n = 17;
auto it = boost::max_element(v | boost::adaptors::strided(n));
std::cout << "max: " << *it << "\n";
}
版画
max: 85
替代用法
您不必全部使用范围算法。您也可以根据需要选择:
#include <boost/range/adaptor/strided.hpp>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v { 1,2,3,4,5,6,7,8,9,10 };
auto v_ = boost::adaptors::stride(v, 7);
auto it = std::max_element(v_.begin(), v_.end());
std::cout << "max: " << *it << "\n";
}
版画
max: 8
有没有办法通过比较每 N 个元素和 return 索引来找到容器中的最大元素。使用 STL、BOOST 或...另一个库?
对于每个 N,我的意思是使用 std::max_element,但将 for 的增量从 ++first 更改为 first += n;
// based on std::max_element
#ifndef NEWTON_ALGORITHM_SEARCH_MAX_INDEX_HPP
#define NEWTON_ALGORITHM_SEARCH_MAX_INDEX_HPP
#include <iterator>
#include <newton/functional.hpp>
namespace newton {
// SAME THAT STD::MAX_ELEMENT
template<class ForwardIt, class Compare>
const ForwardIt max_index(ForwardIt first, ForwardIt last, Compare comp)
{
if ( newton::equal(first, last) ) // newton::equal is basically equivalent to std::equal_to
return last;
ForwardIt largest = first;
while ( newton::not_equal(++first, last) )
if (comp(*largest, *first))
largest = first;
return largest;
}
// possible names
// max_index_some
// max_index_every_n
// max_index__n
template<class ForwardIt, class Size, class Compare>
const ForwardIt max_index_every_n(ForwardIt first, ForwardIt last, Size n, Compare comp)
{
if ( newton::equal(first, last) )
return last;
ForwardIt largest = first;
Size blocks = std::distance(first, last) / n; // integer blocks
if ( newton::greater_equal(blocks, 1) ) {
// if there are exacly N elements, can't sum example
// v.size() = 10, first start in 0, so "0 += 10" is "10", but last index is "9"
// but if mod >= 1, then index is at least 10, so can sum
if ( newton::greater_equal( std::distance(first, last) % n, 1) ) {
for (size_t i = 1; newton::less_equal(i, blocks); ++i, first += n) {
if (comp(*largest, *first))
largest = first;
}
}
else {
for (size_t i = 1; newton::less(i, blocks); ++i, first += n) {
if (comp(*largest, *first))
largest = first;
}
}
}
return largest;
}
template<class ForwardIt>
const ForwardIt max_index(ForwardIt first, ForwardIt last)
{
return max_index(first, last, newton::structure::less());
}
} // newton
如果没有,您尝试将其包含在下一个 STL 版本中的解决方案是什么。 remember
对于 range-v3,它将是:
auto r = v | ranges::view::stride(n);
auto it = ranges::max_element(r);
仅使用 Boost("Range V2" 可以这么说):
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(100);
boost::iota(v, 0);
int n = 17;
auto it = boost::max_element(v | boost::adaptors::strided(n));
std::cout << "max: " << *it << "\n";
}
版画
max: 85
替代用法
您不必全部使用范围算法。您也可以根据需要选择:
#include <boost/range/adaptor/strided.hpp>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v { 1,2,3,4,5,6,7,8,9,10 };
auto v_ = boost::adaptors::stride(v, 7);
auto it = std::max_element(v_.begin(), v_.end());
std::cout << "max: " << *it << "\n";
}
版画
max: 8