使用带有反向迭代器的std :: find()

Using std::find() With Reverse Iterators

本文关键字:std find 迭代器      更新时间:2023-10-16

我很难了解如何使用std::find()函数使用反向迭代器。我相信,如果我能看到一个完成以下任务的示例,我将能够完美理解。

所以,假设我有一个我想搜索的std::vector;但是,我不想搜索典型的方式。我想找到一个从某个索引开始并朝向向量开始的值的首次出现。说明:

   3 |4 |7 |4 |2 |6 |3 |    ^ ^    |< ---------------- |             起点

搜索:给定上述搜索布局的首次出现,为4

预期结果:索引3

我很确定,在这种情况下,必须与反向迭代器一起工作,但我不知道该怎么做。

如果您使用的是std::vector或提供随机访问迭代器的任何其他容器,则可以像使用指针一样使用算术来推进迭代器。您的示例向量有7个元素,您想从索引4开始,因此您可以将正常的迭代器与该元素相关联:

auto i = v.begin() + 4;

对于反向迭代器,您是从向量的背面而不是前后开始的,因此要获得右偏置,您必须从大小中减去所需的索引 1,例如:

auto i = v.rbegin() + (v.size() - 5);

在您的示例中,这将是2,因此反向迭代器将开始指向最后一个元素,然后将两个空间移动到开始,达到您所需的起点。

然后,您可以以正常方式使用std::find

auto found = std::find(v.rbegin() + (v.size() - 5), v.rend(), 4);
if(found == v.rend()) {
    std::cout << "No element found." << std::endl;
} else {
    std::cout << "Index " << (v.rend() - found) << std::endl;
}

请记住,在测试std::find的结果以查看是否找到任何东西时,您需要使用rend()而不是end()。当您将反向迭代器与普通迭代器进行比较时,您将比较实际位置,而不是从一开始就比较偏移,因此v.rend() != v.end()

如果您没有随机访问迭代器(例如,在std::list中),您不能使用指针式算术,因此您可以使用std::advance将迭代剂推向特定位置,并在std::distance之间获得距离两个迭代器。

首先,您设置开始位置:

auto it = v.rbegin() + 2;  // two from the end

然后搜索:

auto kt = std::find(it, v.rend(), 4);

如果kt == v.rend(),找不到元素;否则,我们可以通过简单的距离计算从正面计算索引:

if (kt == v.rend()) {
  std::cerr << "Element 4 not found.n";
  std::abort();
} else {
  auto n = std::distance(kt, v.rend()) - 1;
  std::cout << "Element 4 found at position v[" << n << "].n";
}

尝试以下内容

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
    std::vector<int> v = { 3, 4, 7, 4, 2, 6, 3 };
    std::vector<int>::size_type pos = 4;
    auto it = std::find(std::next(v.rbegin(), v.size() - pos), v.rend(), 4);
    if (it != v.rend())
    {
        std::cout << std::distance(v.begin(), it.base() - 1) << std::endl;
    }
}