【问题标题】:How to find minimum element in a given range of indices for a vector?如何在向量的给定索引范围内找到最小元素?
【发布时间】:2019-06-25 12:25:29
【问题描述】:

如何为std::vector 找到给定索引范围内的最小元素?

假设向量是

vector<int> v = {1,2,3,4,5};

所以

min_element(v.begin(), v.end());

会给1

但是如果我们想要从索引13 的最小值呢?

即在v的元素{2,3,4}中,也就是2

【问题讨论】:

    标签: c++ algorithm c++11 stdvector minimum


    【解决方案1】:

    由于std::min_element 运行在[first, last) 范围内(从first 直到过去的end),我们需要提供:

    const auto begin = v.begin() + 1;
    const auto end = begin + 3;
    int min = *std::min_element(begin, end);
    

    或使用std::next 使其通用(学分@Slava)

    auto min = *std::min_element(std::next(v.begin(), 1), std::next(v.begin(), 4));
    

    将其包装在辅助函数中:

    template<typename Container, typename Predicate = std::less<>>
    auto min_element(
        const Container &container,
        std::size_t startIdx,
        std::size_t endIdx,
        const Predicate pred = {}) -> std::decay_t<decltype(*(container.begin()))>
                                   // typename Container::value_type   // or simply
    {
        return *std::min_element(std::next(container.begin(), startIdx),
                                 std::next(container.begin(), ++endIdx), pred);
    }
    

    现在主要

    std::vector<int> v = { 1, 3, 5, 2, 1 };
    const auto startIndex = 1u, endIndex = 3u;
    const int min = ::min_element(v, startIndex, endIndex /*, predicate if any*/);
    

    See a live example


    但是,请确保给定的迭代器是有效的,否则行为是 UB。

    【讨论】:

    • 使用 std::next() 而不是 + 会使其更通用。
    • min_element() 的结束迭代器不包含在内,就像大多数其他算法一样。因此,要在搜索的元素中包含索引 3,您需要传入 begin+4 作为结束迭代器,而不是 begin+3。否则,使用first = begin+1, end = first+3; min_element(first, end)
    • v.begin() + start, v.begin+end 也会更通用;)
    • min_element() 的第二个参数是一个结束,而不是结束。所以应该是+4 而不是+3 来回答问题。
    • 如果比较元素抛出或内存分配失败,则“以下异常”相当于抛出异常。这些都与迭代器的有效性无关——它们与使用的算法有关。如果迭代器无效(例如在不同的容器中),则行为实际上是未定义的。
    猜你喜欢
    • 1970-01-01
    • 2013-09-09
    • 2012-12-17
    • 2015-01-13
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2019-05-04
    相关资源
    最近更新 更多