【问题标题】:Get all positions of elements in STL vector that are greater than a value获取 STL 向量中大于某个值的元素的所有位置
【发布时间】:2012-10-11 00:09:23
【问题描述】:

我想知道如何找到验证某个条件(例如大于)的元素的索引位置。例如,如果我有一个 int 值向量

vector<int> V;

V 包含值3 2 5 8 2 1 10 4 7

我想获取大于 5 的元素的所有 索引位置。 我知道std::find_if,但根据文档,它只是找到满足条件的第一个元素。

【问题讨论】:

  • 您可以在循环中使用std::find_if,随时存储位置。
  • 反复使用它,不是从头开始,而是从你刚刚找到的地方开始。
  • @oldrinb 实际上我需要获取位置,因为我必须从另一个向量中的相同位置获取元素。
  • @tuxworker,所以你想要索引位置,而不是迭代器?
  • @chris 是的,我想要索引位置

标签: stl vector std c++


【解决方案1】:

在 C++20 中,你可能会这样做

std::ranges::iota_view{0, (int)v.size()}
    | std::ranges::views::filter([&v](int i){ return v[i] > 5; })

Demo

【讨论】:

    【解决方案2】:

    我想我会使用std::copy_if:

    std::vector<int> x{3, 2, 5, 8, 2, 1, 10, 4, 7};
    std::vector<size_t> y(x.size());
    
    std::iota(y.begin(), y.end(), 0);
    std::copy_if(y.begin(), y.end(), 
                 std::ostream_iterator<size_t>(std::cout, " "), 
                 [&](size_t i) { return x[i] > 5; });
    

    对我来说,这给出了3 6 8x 中的 8、10 和 7 的索引——这正是我们想要的。

    如果您坚持使用 C++98/03 编译器/库,您将改用 std::remove_copy_if(并颠倒比较的意思)。在这种情况下,您显然也无法使用 lambda 进行比较。

    【讨论】:

      【解决方案3】:

      只是为了好玩,transform_if算法:

      #include <vector>
      #include <iterator>
      #include <algorithm>
      #include <iostream>
      
      template<typename InputIterator, typename OutputIterator,
          typename UnaryPredicate, typename UnaryFunction>
      OutputIterator
      transform_if (InputIterator first, InputIterator last,
          OutputIterator result, UnaryPredicate pred,
          UnaryFunction func)
      {
          for (; first != last; ++first, ++result)
              if (pred(*first))
                  *result = func(*first);
          return result;
      }
      
      int main()
      {
          std::vector<int> x {3, 2, 5, 8, 2, 1, 10, 4, 7};
          std::vector<size_t> indices;
      
          size_t index = 0;
          transform_if(x.begin(), x.end(), std::back_inserter(indices),
              [&](int i){ return ++index, i > 5; },
              [&](int){ return index-1; });
      
          std::copy(indices.begin(), indices.end(),
                    std::ostream_iterator<size_t>(std::cout, " "));
      }
      

      输出:3 6 8

      【讨论】:

      • 请注意,std 中的某些谓词具有禁止在谓词内修改index 的要求(作为未指定的调用顺序(例如允许并行性))。幸运的是,transform_if 是您的版本,因此您可以控制它。
      【解决方案4】:

      循环std::find_if,从上次停止的地方开始。

      示例 (see it work):

      std::vector<size_t> results;
      
      auto it = std::find_if(std::begin(v), std::end(v), [](int i){return i > 5;});
      while (it != std::end(v)) {
         results.emplace_back(std::distance(std::begin(v), it));
         it = std::find_if(std::next(it), std::end(v), [](int i){return i > 5;});
      }
      

      首先,我们使用第一个结果设置迭代器。如果没有找到,while 循环永远不会执行。否则,存储索引位置(std::distance 基本上是更通用的it - std::begin(v)),然后继续搜索。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-18
        • 2021-11-10
        • 2010-11-13
        • 1970-01-01
        • 2016-11-30
        • 2020-05-10
        • 2021-07-02
        相关资源
        最近更新 更多