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

Posted

技术标签:

【中文标题】如何在向量的给定索引范围内找到最小元素?【英文标题】: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

【问题讨论】:

【参考方案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 来回答问题。 如果比较元素抛出或内存分配失败,则“以下异常”相当于抛出异常。这些都与迭代器的有效性无关——它们与使用的算法有关。如果迭代器无效(例如在不同的容器中),则行为实际上是未定义的。

以上是关于如何在向量的给定索引范围内找到最小元素?的主要内容,如果未能解决你的问题,请参考以下文章

迭代数组并在索引处插入元素

如何有效地将节点添加到段树中以进行最小范围查询?

如何在 AVX 向量中找到元素的索引?

找到给定范围内数字的最大最小差

如何编写一个函数来找到具有最低值的索引

将向量映射到特定范围