查找std::vector中满足条件的最后一个元素

Find last element in std::vector which satisfies a condition

本文关键字:最后一个 条件 元素 std vector 查找 满足      更新时间:2023-10-16

我需要找到向量中小于某个值的最后一个元素。

像find_first_of,但不是first,我想要last。我搜索并发现没有find_last_of,但有find_first_of。

为什么会这样?标准的方法是使用find_first_of与反向迭代器?

使用反向迭代器,如:

#include <iostream>
#include <vector>
int main()
{
  std::vector<int> v{1,2,42,42,63};
  auto result = std::find_if(v.rbegin(), v.rend(),
                             [](int i) { return i == 42; });
  std::cout << std::distance(result, v.rend()) << 'n';
}

现场演示。

对于c++ 20的范围,它将变成

int main()
{
    std::vector<int> v{1,2,42,42,63};
    auto result = std::ranges::find_if(v | std::views::reverse,
                                       [](int i) { return i == 42; });
    std::cout << std::distance(result, v.rend()) << 'n';
}

现场演示。

反向迭代器是这样做的:

std::vector<int> vec = {2,3,10,5,7,11,3,6};  
//below outputs '3':
std::cout << *(std::find_if(vec.rbegin(), vec.rend(), [](int i) { return i < 4; })); 

只有一件事。如果要查找包含谓词元素的范围的尾部,请小心使用谓词:

int main()
{
    std::vector<int> x { 0, 1, 2, 3, 4, 5 };
    // finds the reverse iterator pointing at '2'
    // but using base() to convert back to a forward iterator
    // also 'advances' the resulting forward iterator.
    // in effect, inverting the sense of the predicate to 'v >= 3'
    auto iter = std::find_if(std::make_reverse_iterator(x.end()),
                 std::make_reverse_iterator(x.begin()),
                 [](auto& v) { return v < 3; }).base();
    std::copy(iter,
              x.end(),
              std::ostream_iterator<int>(std::cout, ", "));
}
结果:

3, 4, 5,

From ZenXml:

template <class BidirectionalIterator, class T> inline
BidirectionalIterator find_last(const BidirectionalIterator first, const 
BidirectionalIterator last, const T& value)
{
    for (BidirectionalIterator it = last; it != first;) 
    //reverse iteration: 1. check 2. decrement 3. evaluate
    {
        --it; //
        if (*it == value)
            return it;
    }    
    return last;
}