简体   繁体   English

C++ - 迭代从 find_if 返回的 std::vector<>

[英]C++ - Iterating over std::vector<> returned from find_if

I'm learning C++, so I feel like this should be a very simple answer - but I can't seem to find it.我正在学习 C++,所以我觉得这应该是一个非常简单的答案 - 但我似乎找不到它。 So I apologize in advance if it's naive.所以如果它是幼稚的,我提前道歉。

I have a std::vector<int> of of values, and I am trying to find the indices of the odd values.我有一个std::vector<int>的值,我试图找到数值的索引。

I am following the code from here :我正在关注这里的代码:

(repeated below): (以下重复):

// find_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector

bool IsOdd (int i) {
  return ((i%2)==1);
}

int main () {
  std::vector<int> myvector;

  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);

  std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
  std::cout << "The first odd value is " << *it << '\n';

  return 0;
}

This example prints the first odd value.本示例打印第一个奇数值。 How could I extend this to give me the index values for each of the odd values in myvector ?我怎样才能扩展它来为我提供myvector每个奇数值的索引值? Is this the correct approach?这是正确的方法吗?

// find_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector

bool IsOdd (int i) {
  return ((i%2)==1);
}

int main () {
  std::vector<int> myvector;

  myvector.push_back(10);
  myvector.push_back(25);
  myvector.push_back(40);
  myvector.push_back(55);


  std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd); 
  std::cout << "ODD values are: " << std::endl;     

  while(it != myvector.end() ){

    std::cout << *it  << " in position " << (it - myvector.begin())  << '\n';
    it = std::find_if (++it, myvector.end(), IsOdd); 
  }
  return 0;
}

EDIT: Changed it+1 to ++it see @David Rodríguez - dribeas comment below.编辑:将it+1更改为++it请参阅@David Rodríguez - 下面的 dribeas 评论。

You can increment it and use it as a starting point to iterate further:您可以增加it并将其用作进一步迭代的起点:

std::cout << "odd values: ";
auto it = myvector.begin();
while(it != myvector.end())
{
   it = std::find_if (it, myvector.end(), IsOdd);
   if(it == myvector.end()) break;
   std::cout << *it << ' ';
   ++it;
}
std::cout << endl;

A much more algorithm oriented approach, makes use of copy_if , having an output vector as a result container:一种更加面向算法的方法,使用copy_if ,将输出向量作为结果容器:

std::vector<int> results;
std::copy_if(myvector.begin(), myvector.end(), std::back_inserter(results), IsOdd);

Now results contains the odd values.现在结果包含奇数值。 (Note the back:inserter is in the <iterator> header) (注意后面的:inserter 在<iterator>头中)

You can find the index of a vector iterator (and, more generally, any random-access iterator) by subtracting the start of the sequence:您可以通过减去序列的开头来找到向量迭代器(以及更一般的任何随机访问迭代器)的索引:

std::cout << "The index is " << (it - myvector.begin()) << '\n';

Even more generally, there is a std::distance function which can give you the distance between forward iterators.更普遍的是,有一个std::distance函数可以为您提供前向迭代器之间的距离。 You could use that, for example, if your container were a list ;例如,如果您的容器是一个list ,您可以使用它; but you probably wouldn't want to, since it would be much slower.但您可能不想这样做,因为它会慢得多。

To find all the odd numbers, you'll need a loop to call find again, starting from the element after the one you just found.要查找所有奇数,您需要一个循环来再次调用find ,从刚找到的元素之后的元素开始。

You'll need a loop .你需要一个循环 The iterator-algorithm design of the standard library makes this pretty easy:标准库的迭代器算法设计使这变得非常简单:

#include <iterator>

for (auto it = myvector.begin();
     (it = std::find_if(it, myvector.end(), IsOdd)) != myvector.end(); )
{
    std::cout << *it << " at index " << std::distance(myvector.begin(), it) << "\n";
}

Change these two lines:更改这两行:

std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
std::cout << "The first odd value is " << *it << '\n';

into something like:变成类似的东西:

std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
while ( it != myvector.end() ) {
    std::cout << "The next odd value is " << *it << '\n';
    it = std::find_if (++it, myvector.end(), IsOdd);
}

A nice compact solution could be:一个不错的紧凑解决方案可能是:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main() {
  std::vector<int> const v{1,4,9,11,2,7,8};
  std::cout << "Odd values at indices";
  for(auto b=begin(v), i=b, e=end(v);
      (i=find_if(i,e,[](int a){return a%2==1;})) != e;
      ++i)
    std::cout << ' ' << distance(b,i);
  std::cout.flush();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM