【问题标题】:Using std::find() With Reverse Iterators使用带有反向迭代器的 std::find()
【发布时间】:2017-07-27 02:37:43
【问题描述】:

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

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

3 | 4 | 7| 4| 2| 6| 3| ^ ^ |

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

预期结果:索引 3

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

【问题讨论】:

    标签: c++ algorithm c++11 vector iterator


    【解决方案1】:

    如果您使用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 将迭代器推进到特定位置和 @987654333 @ 获取两个迭代器之间的距离。

    【讨论】:

    • (v.rend() - found) 返回一个太大的索引,例如在这种情况下是 4 而不是预期的索引 3。
    【解决方案2】:

    首先你设置起始位置:

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

    【讨论】:

      【解决方案3】:

      试试下面的方法

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-09
        • 2021-07-24
        • 2013-12-03
        • 2014-08-05
        • 2022-10-07
        • 2018-11-15
        • 2019-02-12
        • 1970-01-01
        相关资源
        最近更新 更多