如何在给定的向量索引范围内找到最小元素?

3

如何在给定的索引范围内查找std::vector中的最小元素?

假设向量为

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

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

给出1

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

也就是在v数组的元素{2,3,4}中,最小值为2

1个回答

10

由于std::min_element函数在范围[first, last)(从firstend的下一个元素)内运行,因此我们需要按照以下方式提供:

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*/);

查看实时示例


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


4
使用std::next()而不是+会使其更通用。 - Slava
min_element() 的末尾迭代器不包括在内,就像大多数其他算法一样。 因此,为了将索引3包含在搜索的元素中,您需要将 begin+4 作为结束迭代器传递,而不是 begin+3。否则,使用 first = begin+1, end = first+3; min_element(first, end) - Remy Lebeau
1
v.begin() + start,v.begin()+end 也更通用 ;) - user10957435
min_element() 的第二个参数是结束位置的下一个位置,而不是结束位置。因此,应该使用 +4 而不是 +3 来回答问题。 - Peter
2
“以下异常”指的是如果比较元素时抛出异常,或者内存分配失败,则会引发异常。这两种情况都与迭代器的有效性无关 - 它们与使用的算法有关。如果迭代器无效(例如在不同的容器中),则行为实际上是未定义的。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接