在std :: adjacent_difference结果上应用某些操作(例如找到min)的最佳方法是什么,而不创建额外的容器?
编辑:手动循环是显而易见的方式,但STL不够。
一种方法是实现output_iterator但看起来有点沉重:
template<typename T>
class find_min_oit {
T min = std::numeric_limits<T>::max();
public:
using iterator_category = std::output_iterator_tag;
find_min_oit& operator++() {
return *this;
}
find_min_oit& operator++(int) {
return *this;
}
find_min_oit& operator*() {
return *this;
}
find_min_oit& operator=(T const& value){
if (value < min){
min = value;
}
return *this;
}
T result() const {
return min;
}
};
void find_min(){
vector<int> arr{1,2,3,6,15};
auto res = std::adjacent_difference(arr.begin(), arr.end(), find_min_oit<int>());
std::cout << res.result() << std::endl;
}
答案 0 :(得分:2)
您可以使用boost::function_output_iterator
来定义迭代器。
void find_min(){
vector<int> arr{1,2,3,6,15};
int result = std::numeric_limits<int>::max();
auto oit = boost::make_function_output_iterator([&result](int value) { result = std::min(value, result); });
std::adjacent_difference(arr.begin(), arr.end(), oit);
std::cout << result << std::endl;
}
答案 1 :(得分:1)
只是去手动循环,不幸的是,标准算法不是在没有成本的情况下组合的......您可以查看range v3库,它允许您以更低成本的方式组合算法
template <class InputIt>
auto find_adjacent_min_v3(InputIt first, InputIt last) {
auto min = std::numeric_limits<typename InputIt::value_type>::max();
for (auto it = first++; first < last; ++first, ++it) {
if (*it - *first < min) {
min = *it - *first;
}
}
return min;
}
为了练习,这是一个使用标准std::accumulate
和自定义“累加器”的版本:
template <class InputIt>
auto find_adjacent_min(InputIt first, InputIt last) {
auto max = std::numeric_limits<typename InputIt::value_type>::max();
return std::accumulate(
std::next(first), last, std::make_pair(*first, max),
[](auto p, auto x) {
auto diff = (x - p.first) < p.second ?
x - p.first : p.second;
return std::make_pair(x, diff);
}).second;
}
答案 2 :(得分:1)
您可以使用std::adjacent_find。
int find_min(){
vector<int> arr{1,2,3,6,15};
int min = std::numeric_limits<int>::max();
std::adjacent_find(arr.begin(), arr.end(), [&](auto a, auto b){
if ((a - b) < min)
min = a-b;
return false;
});
return min;
}
答案 3 :(得分:0)
您有80%的时间来回答您自己的问题:只需添加另一个模板参数typename On_Assignment
,将find_min_oit
重命名为更通用且来自On_Assignment
的内容,以便您可以注入数据成员,然后允许operator=
提供On_Assignment
。然后,您只需要几行来编写带有operator=
的struct,以便在处理adjacent_difference
将提供的值时产生变化。或者,将自定义行为传递给构造函数并将其保存在std::function
中以供operator=
使用:然后您可以传入lambda。
答案 4 :(得分:0)
如果 可以接受输入数据的更改,您可以尝试这样的事情:
std::min_element(x.begin() + 1, std::adjacent_difference(x.begin(), x.end(), x.begin());
CPP reference明确指出允许输入和输出开始相等。