STL:将功能应用于Adchacent_difference的结果,而无需额外的容器

STL: apply function to result of adjacent_difference without extra container

本文关键字:结果 应用于 功能 Adchacent STL difference      更新时间:2023-10-16

在不创建额外容器的情况下,在std :: Adjacent_difference上应用某些操作的最佳方法是什么?

编辑:手动循环是显而易见的,但不够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;
}

您可以使用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;
}

您可以使用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;
}

只需进行手动循环,不幸的是,标准算法不是在没有成本的情况下组合的...您可以查看范围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;
}

您是回答自己的问题的80%:只需添加另一个模板参数typename On_Assignment,将find_min_oit重命名为更通用的内容,并从On_Assignment派生,以便您可以注入数据成员,可以注入数据成员,然后允许operator=On_Assignment提供。然后,您只需要几行即可用operator=编写结构,以在处理值adjacent_difference时产生变化。或者,将自定义行为传递给构造函数,然后将其保存在std::function中以供operator=使用:然后您可以通过lambda。

如果 可以更改输入数据,您可以尝试这样的尝试:

std::min_element(x.begin() + 1, std::adjacent_difference(x.begin(), x.end(), x.begin());

CPP参考状态明确允许输入和输出开始。