簡體   English   中英

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

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

我正在學習 C++,所以我覺得這應該是一個非常簡單的答案 - 但我似乎找不到它。 所以如果它是幼稚的,我提前道歉。

我有一個std::vector<int>的值,我試圖找到數值的索引。

我正在關注這里的代碼:

(以下重復):

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

本示例打印第一個奇數值。 我怎樣才能擴展它來為我提供myvector每個奇數值的索引值? 這是正確的方法嗎?

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

編輯:將it+1更改為++it請參閱@David Rodríguez - 下面的 dribeas 評論。

您可以增加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;

一種更加面向算法的方法,使用copy_if ,將輸出向量作為結果容器:

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

現在結果包含奇數值。 (注意后面的:inserter 在<iterator>頭中)

您可以通過減去序列的開頭來找到向量迭代器(以及更一般的任何隨機訪問迭代器)的索引:

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

更普遍的是,有一個std::distance函數可以為您提供前向迭代器之間的距離。 例如,如果您的容器是一個list ,您可以使用它; 但您可能不想這樣做,因為它會慢得多。

要查找所有奇數,您需要一個循環來再次調用find ,從剛找到的元素之后的元素開始。

你需要一個循環 標准庫的迭代器算法設計使這變得非常簡單:

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

更改這兩行:

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

變成類似的東西:

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

一個不錯的緊湊解決方案可能是:

#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