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

新手上路,请多包涵

我在理解如何将反向迭代器与 std::find() 函数一起使用时遇到了一些麻烦。我相信如果我能看到一个完成以下任务的例子,我就能完美地理解它。

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


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

搜索:根据上述搜索布局,查找第一个匹配项,共 4 个

预期结果:索引 3

我很确定在这种情况下必须使用反向迭代器,但我不知道该怎么做。

原文由 Ethan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

如果您使用 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 得到两个迭代器之间的距离。

原文由 Daniel Eisener 发布,翻译遵循 CC BY-SA 4.0 许可协议

首先你设置开始位置:

 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";
}

原文由 Kerrek SB 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题